-
Notifications
You must be signed in to change notification settings - Fork 23
/
Copy pathBlacklistValidatorUpgradeable.sol
181 lines (153 loc) · 5.26 KB
/
BlacklistValidatorUpgradeable.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
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
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.20;
import "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
import "./IValidator.sol";
/**
* @title BlacklistValidator
* @dev Rejects transfers from blacklisted addresses.
*/
contract BlacklistValidatorUpgradeable is
Initializable,
Ownable2StepUpgradeable,
AccessControlUpgradeable,
UUPSUpgradeable,
IValidator
{
bytes32 public constant ADMIN_ROLE = keccak256("ADMIN_ROLE");
// keccak256("monerium.validator")
bytes32 private constant ID = 0x5341d189213c4172d0c7256f80bc5f8e6350af3aaff7a029625d8dd94f0f82a5;
struct BlacklistValidatorStorage {
mapping(address => bool) blacklist;
}
// keccak256("Monerium.BlacklistValidatorStorage")
bytes32 private constant BlacklistValidatorStorageLocation =
0x187fd434edb52abef1e387c6baed33eabbe6de77c176d95834d5ab434a07fc18;
function _getBlacklistValidatorStorage()
private
pure
returns (BlacklistValidatorStorage storage $)
{
assembly {
$.slot := BlacklistValidatorStorageLocation
}
}
error Unauthorized();
/**
* @dev Emitted when an address is added to the blacklist.
* @param adversary Address added.
*/
event Ban(address indexed adversary);
/**
* @dev Emitted when an address is removed from the blacklist.
* @param friend Address removed.
*/
event Unban(address indexed friend);
/**
* @dev Emitted when admin account is added.
* @param account The address of the account.
*/
event AdminAccountAdded(address indexed account);
/**
* @dev Emitted when admin account is removed.
* @param account The address of the account.
*/
event AdminAccountRemoved(address indexed account);
/// @custom:oz-upgrades-unsafe-allow constructor
constructor() {
_disableInitializers();
}
/**
* @dev Initializes the contract.
*/
function initialize() public initializer {
__Ownable2Step_init();
__Ownable_init(_msgSender());
__AccessControl_init();
}
// _authorizeUpgrade is a crucial part of the UUPS upgrade pattern in OpenZeppelin.
// By defining this function, we can control the upgrade process and prevent unauthorized changes.
// This function can be customized to include additional checks or logic, such as a timelock or a multisig requirement.
function _authorizeUpgrade(
address newImplementation
) internal override onlyOwner {}
// CONTRACT_ID returns the contract identifier.
function CONTRACT_ID() public pure returns (bytes32) {
return ID;
}
/**
* @dev Adds an address to the blacklist.
* @param adversary Address to add.
*/
function ban(address adversary) external onlyAdminAccounts {
BlacklistValidatorStorage storage $ = _getBlacklistValidatorStorage();
$.blacklist[adversary] = true;
emit Ban(adversary);
}
/**
* @dev Removes an address from the blacklist.
* @param friend Address to remove.
*/
function unban(address friend) external onlyAdminAccounts {
BlacklistValidatorStorage storage $ = _getBlacklistValidatorStorage();
$.blacklist[friend] = false;
emit Unban(friend);
}
/**
* @dev Checks if an address is in the blacklist.
* @param account Address to check.
* @return true if the address is in the blacklist.
*/
function isBan(address account) external view returns (bool) {
BlacklistValidatorStorage storage $ = _getBlacklistValidatorStorage();
return $.blacklist[account];
}
/**
* @dev Validates token transfer.
* Implements IValidator interface.
*/
function validate(
address from,
address to,
uint256 amount
) external returns (bool valid) {
BlacklistValidatorStorage storage $ = _getBlacklistValidatorStorage();
valid = !($.blacklist[from]);
emit Decision(from, to, amount, valid);
}
/**
* @dev modifier to restrict access to admin accounts.
*/
modifier onlyAdminAccounts() {
if (!isAdminAccount(_msgSender())) {
revert Unauthorized();
}
_;
}
/**
* @dev Checks wether an address is a admin account.
* @param account The address of the account.
* @return true if admin account.
*/
function isAdminAccount(address account) public view returns (bool) {
return hasRole(ADMIN_ROLE, account);
}
/**
* @dev add admin account.
* @param account The address of the account.
*/
function addAdminAccount(address account) public virtual onlyOwner {
_grantRole(ADMIN_ROLE, account);
emit AdminAccountAdded(account);
}
/**
* @dev remove admin account.
* @param account The address of the account.
*/
function removeAdminAccount(address account) public virtual onlyOwner {
_revokeRole(ADMIN_ROLE, account);
emit AdminAccountRemoved(account);
}
}