Skip to content

Commit 436b8a6

Browse files
committed
feat: create an anonymous implementation of Pausable
1 parent 0cc4f40 commit 436b8a6

File tree

1 file changed

+136
-0
lines changed

1 file changed

+136
-0
lines changed
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
// SPDX-License-Identifier: MIT
2+
pragma solidity ^0.8.24;
3+
4+
import {Context} from "@openzeppelin/contracts/utils/Context.sol";
5+
6+
/**
7+
* @title AnonymousPausable
8+
* @dev Contract module which allows children to implement an emergency stop
9+
* mechanism that can be triggered by an authorized account with enhanced privacy.
10+
*
11+
* Based on OpenZeppelin Contracts (last updated v5.3.0) (utils/Pausable.sol)
12+
* with modifications for anonymous pause functionality.
13+
*
14+
* This module is used through inheritance. It will make available the
15+
* modifiers `whenNotPaused` and `whenPaused`, which can be applied to
16+
* the functions of your contract. Note that they will not be pausable by
17+
* simply including this module, only once the modifiers are put in place.
18+
*
19+
* Key differences from OpenZeppelin's Pausable:
20+
* - Pause events emit with address(0) to preserve anonymity of the pause controller
21+
* - Maintains transparency about pause state changes while protecting operator privacy
22+
* - Virtual event emission functions (_emitPaused, _emitUnpaused) for maximum customization flexibility
23+
* - Enables custom event logic without requiring full function overrides or losing state management
24+
*/
25+
abstract contract AnonymousPausable is Context {
26+
bool private _paused;
27+
28+
/**
29+
* @dev Emitted when the pause is triggered. Account is anonymized for privacy.
30+
*/
31+
event Paused(address account);
32+
33+
/**
34+
* @dev Emitted when the pause is lifted. Account is anonymized for privacy.
35+
*/
36+
event Unpaused(address account);
37+
38+
/**
39+
* @dev The operation failed because the contract is paused.
40+
*/
41+
error EnforcedPause();
42+
43+
/**
44+
* @dev The operation failed because the contract is not paused.
45+
*/
46+
error ExpectedPause();
47+
48+
/**
49+
* @dev Modifier to make a function callable only when the contract is not paused.
50+
*
51+
* Requirements:
52+
*
53+
* - The contract must not be paused.
54+
*/
55+
modifier whenNotPaused() {
56+
_requireNotPaused();
57+
_;
58+
}
59+
60+
/**
61+
* @dev Modifier to make a function callable only when the contract is paused.
62+
*
63+
* Requirements:
64+
*
65+
* - The contract must be paused.
66+
*/
67+
modifier whenPaused() {
68+
_requirePaused();
69+
_;
70+
}
71+
72+
/**
73+
* @dev Returns true if the contract is paused, and false otherwise.
74+
*/
75+
function paused() public view virtual returns (bool) {
76+
return _paused;
77+
}
78+
79+
/**
80+
* @dev Throws if the contract is paused.
81+
*/
82+
function _requireNotPaused() internal view virtual {
83+
if (paused()) {
84+
revert EnforcedPause();
85+
}
86+
}
87+
88+
/**
89+
* @dev Throws if the contract is not paused.
90+
*/
91+
function _requirePaused() internal view virtual {
92+
if (!paused()) {
93+
revert ExpectedPause();
94+
}
95+
}
96+
97+
/**
98+
* @dev Triggers stopped state.
99+
*
100+
* Requirements:
101+
*
102+
* - The contract must not be paused.
103+
*/
104+
function _pause() internal virtual whenNotPaused {
105+
_paused = true;
106+
_emitPaused();
107+
}
108+
109+
/**
110+
* @dev Returns to normal state.
111+
*
112+
* Requirements:
113+
*
114+
* - The contract must be paused.
115+
*/
116+
function _unpause() internal virtual whenPaused {
117+
_paused = false;
118+
_emitUnpaused();
119+
}
120+
121+
/**
122+
* @dev Emits the Paused event. Can be overridden to customize event emission.
123+
* Default implementation emits with address(0) for anonymity.
124+
*/
125+
function _emitPaused() internal virtual {
126+
emit Paused(address(0));
127+
}
128+
129+
/**
130+
* @dev Emits the Unpaused event. Can be overridden to customize event emission.
131+
* Default implementation emits with address(0) for anonymity.
132+
*/
133+
function _emitUnpaused() internal virtual {
134+
emit Unpaused(address(0));
135+
}
136+
}

0 commit comments

Comments
 (0)