-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMultiProxyController.sol
146 lines (126 loc) · 4.32 KB
/
MultiProxyController.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../util/Ownable.sol";
import "../interface/IAdminUpgradeabilityProxy.sol";
contract MultiProxyController is Ownable {
struct Proxy {
string name;
IAdminUpgradeabilityProxy proxy;
address impl;
}
Proxy[] private proxies;
event ProxyAdded(string name, address proxy);
event ProxyRemoved(uint256 index);
event ProxyAdminChanged(uint256 index, address newAdmin);
constructor(string[] memory _names, address[] memory _proxies) Ownable() {
uint256 length = _proxies.length;
require(_names.length == length, "Not equal length");
for (uint256 i; i < length; i++) {
addProxy(_names[i], _proxies[i]);
}
}
function upgradeProxyTo(uint256 index, address newImpl) public onlyOwner {
require(index < proxies.length, "Out of bounds");
proxies[index].proxy.upgradeTo(newImpl);
}
function changeProxyAdmin(uint256 index, address newAdmin)
public
onlyOwner
{
require(index < proxies.length, "Out of bounds");
proxies[index].proxy.changeAdmin(newAdmin);
emit ProxyAdminChanged(index, newAdmin);
}
function addProxy(string memory name, address proxy) public onlyOwner {
IAdminUpgradeabilityProxy _proxy = IAdminUpgradeabilityProxy(proxy);
proxies.push(Proxy(name, _proxy, address(0)));
emit ProxyAdded(name, proxy);
}
function removeProxy(uint256 index) public onlyOwner {
// Preferably want to maintain order to reduce chance of mistake.
uint256 length = proxies.length;
if (index >= length) return;
for (uint256 i = index; i < length - 1; ++i) {
proxies[i] = proxies[i + 1];
}
proxies.pop();
emit ProxyRemoved(index);
}
function changeAllAdmins(address newAdmin) public onlyOwner {
uint256 length = proxies.length;
for (uint256 i; i < length; ++i) {
changeProxyAdmin(i, newAdmin);
}
}
function changeAllAdmins(
uint256 start,
uint256 count,
address newAdmin
) public onlyOwner {
require(start + count <= proxies.length, "Out of bounds");
for (uint256 i = start; i < start + count; ++i) {
changeProxyAdmin(i, newAdmin);
}
}
function getName(uint256 index) public view returns (string memory) {
return proxies[index].name;
}
function getAdmin(uint256 index) public view returns (address) {
return proxies[index].proxy.admin();
}
function getImpl(uint256 index) public view returns (address) {
return proxies[index].proxy.implementation();
}
function getAllProxiesInfo() public view returns (string[] memory) {
uint256 length = proxies.length;
string[] memory proxyInfos = new string[](length);
for (uint256 i; i < length; ++i) {
Proxy memory _proxy = proxies[i];
proxyInfos[i] = string(
abi.encodePacked(uint2str(i), ": ", _proxy.name)
);
}
return proxyInfos;
}
function getAllProxies() public view returns (address[] memory) {
uint256 length = proxies.length;
address[] memory proxyInfos = new address[](length);
for (uint256 i; i < length; ++i) {
proxyInfos[i] = address(proxies[i].proxy);
}
return proxyInfos;
}
function getAllImpls() public view returns (address[] memory) {
uint256 length = proxies.length;
address[] memory proxyInfos = new address[](length);
for (uint256 i; i < length; ++i) {
proxyInfos[i] = address(proxies[i].proxy.implementation());
}
return proxyInfos;
}
function uint2str(uint256 _i)
internal
pure
returns (string memory _uintAsString)
{
if (_i == 0) {
return "0";
}
uint256 j = _i;
uint256 len;
while (j != 0) {
len++;
j /= 10;
}
bytes memory bstr = new bytes(len);
uint256 k = len;
while (_i != 0) {
k = k - 1;
uint8 temp = (48 + uint8(_i - (_i / 10) * 10));
bytes1 b1 = bytes1(temp);
bstr[k] = b1;
_i /= 10;
}
return string(bstr);
}
}