@@ -6,20 +6,34 @@ pragma solidity 0.5.17;
66 * @dev Governance owned registry of approved contracts and roles.
77 */
88contract Registry {
9+ enum ContractStatus {New, Approved, Disabled}
910
10- enum ContractStatus { New, Approved, Disabled }
11-
12- // Governance role is to enable recovery from key compromise by rekeying other roles .
11+ // Governance role is to enable recovery from key compromise by rekeying
12+ // other roles. Also, it can disable operator contract panic buttons
13+ // permanently .
1314 address internal governance;
1415
1516 // Registry Keeper maintains approved operator contracts. Each operator
1617 // contract must be approved before it can be authorized by a staker or
1718 // used by a service contract.
1819 address internal registryKeeper;
1920
20- // The Panic Button can disable malicious or malfunctioning contracts
21- // that have been previously approved by the Registry Keeper.
22- address internal panicButton;
21+ // Each operator contract has a Panic Button which can disable malicious
22+ // or malfunctioning contract that have been previously approved by the
23+ // Registry Keeper.
24+ //
25+ // New operator contract added to the registry has a default panic button
26+ // value assigned (defaultPanicButton). Panic button for each operator
27+ // contract can be later updated by Governance to individual value.
28+ //
29+ // It is possible to disable panic button for individual contract by
30+ // setting the panic button to zero address. In such case, operator contract
31+ // can not be disabled and is permanently approved in the registry.
32+ mapping (address => address ) public panicButtons;
33+
34+ // Default panic button for each new operator contract added to the
35+ // registry. Can be later updated for each contract.
36+ address internal defaultPanicButton;
2337
2438 // Each service contract has a Operator Contract Upgrader whose purpose
2539 // is to manage operator contracts for that specific service contract.
@@ -35,8 +49,16 @@ contract Registry {
3549
3650 event GovernanceUpdated ();
3751 event RegistryKeeperUpdated ();
38- event PanicButtonUpdated ();
39- event OperatorContractUpgraderUpdated (address serviceContract , address upgrader );
52+ event DefaultPanicButtonUpdated ();
53+ event OperatorContractPanicButtonDisabled (address operatorContract );
54+ event OperatorContractPanicButtonUpdated (
55+ address operatorContract ,
56+ address panicButton
57+ );
58+ event OperatorContractUpgraderUpdated (
59+ address serviceContract ,
60+ address upgrader
61+ );
4062
4163 modifier onlyGovernance () {
4264 require (governance == msg .sender , "Not authorized " );
@@ -48,15 +70,33 @@ contract Registry {
4870 _;
4971 }
5072
51- modifier onlyPanicButton () {
73+ modifier onlyPanicButton (address _operatorContract ) {
74+ address panicButton = panicButtons[_operatorContract];
75+ require (panicButton != address (0 ), "Panic button disabled " );
5276 require (panicButton == msg .sender , "Not authorized " );
5377 _;
5478 }
5579
80+ modifier onlyForNewContract (address _operatorContract ) {
81+ require (
82+ isNewOperatorContract (_operatorContract),
83+ "Not a new operator contract "
84+ );
85+ _;
86+ }
87+
88+ modifier onlyForApprovedContract (address _operatorContract ) {
89+ require (
90+ isApprovedOperatorContract (_operatorContract),
91+ "Not an approved operator contract "
92+ );
93+ _;
94+ }
95+
5696 constructor () public {
5797 governance = msg .sender ;
5898 registryKeeper = msg .sender ;
59- panicButton = msg .sender ;
99+ defaultPanicButton = msg .sender ;
60100 }
61101
62102 function setGovernance (address _governance ) public onlyGovernance {
@@ -69,45 +109,98 @@ contract Registry {
69109 emit RegistryKeeperUpdated ();
70110 }
71111
72- function setPanicButton (address _panicButton ) public onlyGovernance {
73- panicButton = _panicButton;
74- emit PanicButtonUpdated ();
112+ function setDefaultPanicButton (address _panicButton ) public onlyGovernance {
113+ defaultPanicButton = _panicButton;
114+ emit DefaultPanicButtonUpdated ();
75115 }
76116
77- function setOperatorContractUpgrader (address _serviceContract , address _operatorContractUpgrader ) public onlyGovernance {
78- operatorContractUpgraders[_serviceContract] = _operatorContractUpgrader;
79- emit OperatorContractUpgraderUpdated (_serviceContract, _operatorContractUpgrader);
117+ function setOperatorContractPanicButton (
118+ address _operatorContract ,
119+ address _panicButton
120+ ) public onlyForApprovedContract (_operatorContract) onlyGovernance {
121+ require (
122+ panicButtons[_operatorContract] != address (0 ),
123+ "Disabled panic button cannot be updated "
124+ );
125+ require (
126+ _panicButton != address (0 ),
127+ "Panic button must be non-zero address "
128+ );
129+
130+ panicButtons[_operatorContract] = _panicButton;
131+
132+ emit OperatorContractPanicButtonUpdated (
133+ _operatorContract,
134+ _panicButton
135+ );
80136 }
81137
82- function approveOperatorContract (address operatorContract ) public onlyRegistryKeeper {
138+ function disableOperatorContractPanicButton (address _operatorContract )
139+ public
140+ onlyForApprovedContract (_operatorContract)
141+ onlyGovernance
142+ {
83143 require (
84- isNewOperatorContract (operatorContract ),
85- "Only new operator contracts can be approved "
144+ panicButtons[_operatorContract] != address ( 0 ),
145+ "Panic button already disabled "
86146 );
87147
88- operatorContracts[operatorContract] = ContractStatus.Approved;
89- emit OperatorContractApproved (operatorContract);
148+ panicButtons[_operatorContract] = address (0 );
149+
150+ emit OperatorContractPanicButtonDisabled (_operatorContract);
90151 }
91152
92- function disableOperatorContract (address operatorContract ) public onlyPanicButton {
93- require (
94- isApprovedOperatorContract (operatorContract),
95- "Only approved operator contracts can be disabled "
153+ function setOperatorContractUpgrader (
154+ address _serviceContract ,
155+ address _operatorContractUpgrader
156+ ) public onlyGovernance {
157+ operatorContractUpgraders[_serviceContract] = _operatorContractUpgrader;
158+ emit OperatorContractUpgraderUpdated (
159+ _serviceContract,
160+ _operatorContractUpgrader
96161 );
162+ }
163+
164+ function approveOperatorContract (address operatorContract )
165+ public
166+ onlyForNewContract (operatorContract)
167+ onlyRegistryKeeper
168+ {
169+ operatorContracts[operatorContract] = ContractStatus.Approved;
170+ panicButtons[operatorContract] = defaultPanicButton;
171+ emit OperatorContractApproved (operatorContract);
172+ }
97173
174+ function disableOperatorContract (address operatorContract )
175+ public
176+ onlyForApprovedContract (operatorContract)
177+ onlyPanicButton (operatorContract)
178+ {
98179 operatorContracts[operatorContract] = ContractStatus.Disabled;
99180 emit OperatorContractDisabled (operatorContract);
100181 }
101182
102- function isNewOperatorContract (address operatorContract ) public view returns (bool ) {
183+ function isNewOperatorContract (address operatorContract )
184+ public
185+ view
186+ returns (bool )
187+ {
103188 return operatorContracts[operatorContract] == ContractStatus.New;
104189 }
105190
106- function isApprovedOperatorContract (address operatorContract ) public view returns (bool ) {
191+ function isApprovedOperatorContract (address operatorContract )
192+ public
193+ view
194+ returns (bool )
195+ {
107196 return operatorContracts[operatorContract] == ContractStatus.Approved;
108197 }
109198
110- function operatorContractUpgraderFor (address _serviceContract ) public view returns (address ) {
199+ function operatorContractUpgraderFor (address _serviceContract )
200+ public
201+ view
202+ returns (address )
203+ {
111204 return operatorContractUpgraders[_serviceContract];
112205 }
113206}
0 commit comments