-
Notifications
You must be signed in to change notification settings - Fork 36
Expand file tree
/
Copy pathPauseController.sol
More file actions
183 lines (138 loc) · 6.03 KB
/
PauseController.sol
File metadata and controls
183 lines (138 loc) · 6.03 KB
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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import {IPausable} from "./IPausable.sol";
import {ScrollOwner} from "./ScrollOwner.sol";
/// @title PauseController
/// @notice This contract is used to pause and unpause components in Scroll.
/// @dev The owner of this contract should be `ScrollOwner` contract to allow fine-grained control over the pause and unpause of components.
contract PauseController is OwnableUpgradeable {
/**********
* Events *
**********/
/// @notice Emitted when a component is paused.
/// @param component The component that is paused.
event Pause(address indexed component);
/// @notice Emitted when a component is unpaused.
/// @param component The component that is unpaused.
event Unpause(address indexed component);
/// @notice Emitted when the pause cooldown period of a component is reset.
/// @param component The component that has its pause cooldown period reset.
event ResetPauseCooldownPeriod(address indexed component);
/// @notice Emitted when the pause cooldown period is updated.
/// @param oldPauseCooldownPeriod The old pause cooldown period.
/// @param newPauseCooldownPeriod The new pause cooldown period.
event UpdatePauseCooldownPeriod(uint256 oldPauseCooldownPeriod, uint256 newPauseCooldownPeriod);
/**********
* Errors *
**********/
/// @dev Thrown when the cooldown period is not passed.
error ErrorCooldownPeriodNotPassed();
/// @dev Thrown when the component is already paused.
error ErrorComponentAlreadyPaused();
/// @dev Thrown when the component is not paused.
error ErrorComponentNotPaused();
/// @dev Thrown when the execution of `ScrollOwner` contract fails.
error ErrorExecutePauseFailed();
/// @dev Thrown when the execution of `ScrollOwner` contract fails.
error ErrorExecuteUnpauseFailed();
/*************
* Constants *
*************/
/// @notice The role for pause controller in `ScrollOwner` contract.
bytes32 public constant PAUSE_CONTROLLER_ROLE = keccak256("PAUSE_CONTROLLER_ROLE");
/***********************
* Immutable Variables *
***********************/
/// @notice The address of the ScrollOwner contract.
address public immutable SCROLL_OWNER;
/*********************
* Storage Variables *
*********************/
/// @notice The pause cooldown period. That is the minimum time between two consecutive pauses.
uint256 public pauseCooldownPeriod;
/// @notice The last unpause time of each component.
mapping(address => uint256) private lastUnpauseTime;
/***************
* Constructor *
***************/
constructor(address _scrollOwner) {
SCROLL_OWNER = _scrollOwner;
_disableInitializers();
}
function initialize(uint256 _pauseCooldownPeriod) external initializer {
__Ownable_init();
_updatePauseCooldownPeriod(_pauseCooldownPeriod);
}
/*************************
* Public View Functions *
*************************/
/// @notice Get the last unpause timestamp of a component.
/// @param component The component to get the last unpause timestamp.
/// @return The last unpause timestamp of the component.
function getLastUnpauseTime(IPausable component) external view returns (uint256) {
return lastUnpauseTime[address(component)];
}
/************************
* Restricted Functions *
************************/
/// @notice Pause a component.
/// @param component The component to pause.
function pause(IPausable component) external onlyOwner {
if (component.paused()) {
revert ErrorComponentAlreadyPaused();
}
if (lastUnpauseTime[address(component)] + pauseCooldownPeriod >= block.timestamp) {
revert ErrorCooldownPeriodNotPassed();
}
ScrollOwner(payable(SCROLL_OWNER)).execute(
address(component),
0,
abi.encodeWithSelector(IPausable.setPause.selector, true),
PAUSE_CONTROLLER_ROLE
);
if (!component.paused()) {
revert ErrorExecutePauseFailed();
}
emit Pause(address(component));
}
/// @notice Unpause a component.
/// @param component The component to unpause.
function unpause(IPausable component) external onlyOwner {
if (!component.paused()) {
revert ErrorComponentNotPaused();
}
ScrollOwner(payable(SCROLL_OWNER)).execute(
address(component),
0,
abi.encodeWithSelector(IPausable.setPause.selector, false),
PAUSE_CONTROLLER_ROLE
);
lastUnpauseTime[address(component)] = block.timestamp;
if (component.paused()) {
revert ErrorExecuteUnpauseFailed();
}
emit Unpause(address(component));
}
/// @notice Reset the pause cooldown period of a component.
/// @param component The component to reset the pause cooldown period.
function resetPauseCooldownPeriod(IPausable component) external onlyOwner {
lastUnpauseTime[address(component)] = 0;
emit ResetPauseCooldownPeriod(address(component));
}
/// @notice Set the pause cooldown period.
/// @param newPauseCooldownPeriod The new pause cooldown period.
function updatePauseCooldownPeriod(uint256 newPauseCooldownPeriod) external onlyOwner {
_updatePauseCooldownPeriod(newPauseCooldownPeriod);
}
/**********************
* Internal Functions *
**********************/
/// @dev Internal function to set the pause cooldown period.
/// @param newPauseCooldownPeriod The new pause cooldown period.
function _updatePauseCooldownPeriod(uint256 newPauseCooldownPeriod) internal {
uint256 oldPauseCooldownPeriod = pauseCooldownPeriod;
pauseCooldownPeriod = newPauseCooldownPeriod;
emit UpdatePauseCooldownPeriod(oldPauseCooldownPeriod, newPauseCooldownPeriod);
}
}