/
IonPausableUpgradeable.sol
124 lines (109 loc) · 3.79 KB
/
IonPausableUpgradeable.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
// SPDX-License-Identifier: MIT
pragma solidity 0.8.21;
import { ContextUpgradeable } from "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol";
/**
* @dev A copy of OpenZeppelin's `Pausable` module but with an array of pause
* booleans as opposed to one. This will allow for a more granular pausing set
* up.
*
* `IonPool` will require three types of pausing. One pause is for halting
* actions that put the protocol into a further unsafe state (e.g. borrows,
* withdraws of base), one for pausing actions that put the protocol into a
* safer state (e.g. repays, deposits of base), and one for pausing the accrual
* of interest rates. Depnding on the situation, it may be desirable to pause
* one, two, or all of these, hence the reasoning for this design.
*/
abstract contract IonPausableUpgradeable is ContextUpgradeable {
enum Pauses {
UNSAFE,
SAFE
}
struct IonPausableStorage {
// Initialized to unpaused implicitly
bool[2] _pausedStates;
}
// keccak256(abi.encode(uint256(keccak256("ion.storage.IonPausable")) - 1)) & ~bytes32(uint256(0xff))
// solhint-disable-next-line
bytes32 private constant IonPausableStorageLocation =
0x48c3e72c7d0b1210a7962d468cc626eef9908fe8b8be51a049f423a1848bb700;
function _getIonPausableStorage() private pure returns (IonPausableStorage storage $) {
assembly {
$.slot := IonPausableStorageLocation
}
}
error EnforcedPause(Pauses pauseIndex);
error ExpectedPause(Pauses pauseIndex);
/**
* @dev Emitted when the pause is triggered by `account`.
*/
event Paused(Pauses indexed pauseIndex, address account);
/**
* @dev Emitted when the pause is lifted by `account`.
*/
event Unpaused(Pauses indexed pauseIndex, address account);
/**
* @dev Modifier to make a function callable only when the contract is not paused.
*
* Requirements:
*
* - The contract must not be paused.
*/
modifier whenNotPaused(Pauses pauseIndex) {
_requireNotPaused(pauseIndex);
_;
}
/**
* @dev Modifier to make a function callable only when the contract is paused.
*
* Requirements:
*
* - The contract must be paused.
*/
modifier whenPaused(Pauses pauseIndex) {
_requirePaused(pauseIndex);
_;
}
/**
* @dev Returns true if the contract is paused, and false otherwise.
*/
function paused(Pauses pauseIndex) public view virtual returns (bool) {
IonPausableStorage storage $ = _getIonPausableStorage();
return $._pausedStates[uint256(pauseIndex)];
}
/**
* @dev Throws if the contract is paused.
*/
function _requireNotPaused(Pauses pauseIndex) internal view virtual {
if (paused(pauseIndex)) revert EnforcedPause(pauseIndex);
}
/**
* @dev Throws if the contract is not paused.
*/
function _requirePaused(Pauses pauseIndex) internal view virtual {
if (!paused(pauseIndex)) revert ExpectedPause(pauseIndex);
}
/**
* @dev Triggers stopped state.
*
* Requirements:
*
* - The contract must not be paused.
*/
function _pause(Pauses pauseIndex) internal virtual whenNotPaused(pauseIndex) {
IonPausableStorage storage $ = _getIonPausableStorage();
$._pausedStates[uint256(pauseIndex)] = true;
emit Paused(pauseIndex, _msgSender());
}
/**
* @dev Returns to normal state.
*
* Requirements:
*
* - The contract must be paused.
*/
function _unpause(Pauses pauseIndex) internal virtual whenPaused(pauseIndex) {
IonPausableStorage storage $ = _getIonPausableStorage();
$._pausedStates[uint256(pauseIndex)] = false;
emit Unpaused(pauseIndex, _msgSender());
}
}