0
# Security Utilities
1
2
Essential security patterns including reentrancy guards, pausable functionality, multicall batching, and cryptographic utilities for signature verification and secure smart contract development.
3
4
## Capabilities
5
6
### Reentrancy Guard
7
8
Protection against reentrancy attacks using storage-based guards.
9
10
```solidity { .api }
11
/**
12
* @dev Contract module that helps prevent reentrant calls
13
*/
14
abstract contract ReentrancyGuardUpgradeable {
15
function __ReentrancyGuard_init() internal onlyInitializing;
16
17
/**
18
* @dev Prevents a contract from calling itself, directly or indirectly
19
*/
20
modifier nonReentrant();
21
}
22
23
/**
24
* @dev Variant using transient storage (EIP-1153)
25
*/
26
abstract contract ReentrancyGuardTransientUpgradeable {
27
function __ReentrancyGuardTransient_init() internal onlyInitializing;
28
29
/**
30
* @dev Prevents reentrancy using transient storage
31
*/
32
modifier nonReentrant();
33
}
34
```
35
36
### Pausable Contract
37
38
Emergency pause functionality for contracts.
39
40
```solidity { .api }
41
/**
42
* @dev Contract module which allows children to implement an emergency stop mechanism
43
*/
44
abstract contract PausableUpgradeable {
45
function __Pausable_init() internal onlyInitializing;
46
47
/**
48
* @dev Returns true if the contract is paused
49
*/
50
function paused() external view returns (bool);
51
52
/**
53
* @dev Modifier to make a function callable only when the contract is not paused
54
*/
55
modifier whenNotPaused();
56
57
/**
58
* @dev Modifier to make a function callable only when the contract is paused
59
*/
60
modifier whenPaused();
61
62
/**
63
* @dev Triggers stopped state (internal function)
64
*/
65
function _pause() internal;
66
67
/**
68
* @dev Returns to normal state (internal function)
69
*/
70
function _unpause() internal;
71
}
72
73
// Events
74
event Paused(address account);
75
event Unpaused(address account);
76
```
77
78
### Multicall
79
80
Batch multiple function calls in a single transaction.
81
82
```solidity { .api }
83
/**
84
* @dev Provides a function to batch together multiple calls
85
*/
86
abstract contract MulticallUpgradeable {
87
function __Multicall_init() internal onlyInitializing;
88
89
/**
90
* @dev Receives and executes a batch of function calls on this contract
91
*/
92
function multicall(bytes[] calldata data) external returns (bytes[] memory results);
93
}
94
```
95
96
### Nonce Management
97
98
Nonce tracking for signature-based operations.
99
100
```solidity { .api }
101
/**
102
* @dev Provides tracking nonces for addresses
103
*/
104
abstract contract NoncesUpgradeable {
105
function __Nonces_init() internal onlyInitializing;
106
107
/**
108
* @dev Returns the current nonce for owner
109
*/
110
function nonces(address owner) external view returns (uint256);
111
112
/**
113
* @dev Consumes a nonce and returns the current value
114
*/
115
function _useNonce(address owner) internal returns (uint256);
116
117
/**
118
* @dev Consumes a specific nonce
119
*/
120
function _useCheckedNonce(address owner, uint256 nonce) internal;
121
}
122
123
/**
124
* @dev Variant that supports keyed nonces
125
*/
126
abstract contract NoncesKeyedUpgradeable {
127
function __NoncesKeyed_init() internal onlyInitializing;
128
129
/**
130
* @dev Returns the nonce for owner and key
131
*/
132
function nonces(address owner, bytes32 key) external view returns (uint256);
133
134
/**
135
* @dev Consumes a keyed nonce
136
*/
137
function _useNonce(address owner, bytes32 key) internal returns (uint256);
138
139
/**
140
* @dev Consumes a specific keyed nonce
141
*/
142
function _useCheckedNonce(address owner, bytes32 key, uint256 nonce) internal;
143
}
144
```
145
146
### Cryptographic Utilities
147
148
#### EIP-712 Domain Separator
149
150
```solidity { .api }
151
/**
152
* @dev Implementation of EIP-712 domain separator and typed data hashing
153
*/
154
abstract contract EIP712Upgradeable {
155
function __EIP712_init(string memory name, string memory version) internal onlyInitializing;
156
157
/**
158
* @dev Returns the domain separator for the current chain
159
*/
160
function _domainSeparatorV4() internal view returns (bytes32);
161
162
/**
163
* @dev Hash typed data according to EIP-712
164
*/
165
function _hashTypedDataV4(bytes32 structHash) internal view returns (bytes32);
166
167
/**
168
* @dev Returns the fields and values that describe the domain separator
169
*/
170
function eip712Domain() external view returns (
171
bytes1 fields,
172
string memory name,
173
string memory version,
174
uint256 chainId,
175
address verifyingContract,
176
bytes32 salt,
177
uint256[] memory extensions
178
);
179
}
180
```
181
182
#### Interface Detection (ERC-165)
183
184
```solidity { .api }
185
/**
186
* @dev Implementation of the ERC-165 standard for interface detection
187
*/
188
abstract contract ERC165Upgradeable {
189
function __ERC165_init() internal onlyInitializing;
190
191
/**
192
* @dev Returns true if this contract implements the interface defined by interfaceId
193
*/
194
function supportsInterface(bytes4 interfaceId) external view returns (bool);
195
}
196
```
197
198
#### Signature Verification
199
200
```solidity { .api }
201
/**
202
* @dev ECDSA signature verification utilities
203
*/
204
library ECDSAUpgradeable {
205
/**
206
* @dev Recovers the signer of the hash using ECDSA
207
*/
208
function recover(bytes32 hash, bytes memory signature) internal pure returns (address);
209
210
/**
211
* @dev Recovers signer from hash and signature components
212
*/
213
function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address);
214
215
/**
216
* @dev Returns an Ethereum Signed Message, created from a hash
217
*/
218
function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32);
219
220
/**
221
* @dev Returns an Ethereum Signed Message, created from a string
222
*/
223
function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32);
224
}
225
226
/**
227
* @dev P256 (secp256r1) signature verification
228
*/
229
library P256Upgradeable {
230
/**
231
* @dev Verifies a P256 signature
232
*/
233
function verify(bytes32 hash, bytes32 r, bytes32 s, bytes32 x, bytes32 y) internal view returns (bool);
234
}
235
236
/**
237
* @dev RSA signature verification utilities
238
*/
239
library RSAUpgradeable {
240
/**
241
* @dev Verifies an RSA signature using PKCS1 v1.5 padding
242
*/
243
function pkcs1Sha256(bytes memory message, bytes memory signature, bytes memory modulus, bytes memory exponent) internal view returns (bool);
244
}
245
```
246
247
### Cryptographic Signers
248
249
Modular signature verification contracts that implement various cryptographic signature schemes for smart contract accounts.
250
251
#### ECDSA Signer
252
253
```solidity { .api }
254
/**
255
* @dev ECDSA signature verification signer for account abstraction
256
*/
257
abstract contract SignerECDSAUpgradeable {
258
function __SignerECDSA_init(address signerAddr) internal onlyInitializing;
259
260
/**
261
* @dev Sets the signer address
262
*/
263
function _setSigner(address signerAddr) internal;
264
265
/**
266
* @dev Validates an ECDSA signature
267
*/
268
function _validateSignature(bytes32 hash, bytes calldata signature) internal view returns (bool);
269
}
270
```
271
272
#### P256 Signer
273
274
```solidity { .api }
275
/**
276
* @dev P256 (secp256r1) signature verification signer
277
*/
278
abstract contract SignerP256Upgradeable {
279
function __SignerP256_init(bytes32 qx, bytes32 qy) internal onlyInitializing;
280
281
/**
282
* @dev Sets the P256 public key
283
*/
284
function _setSigner(bytes32 qx, bytes32 qy) internal;
285
286
/**
287
* @dev Validates a P256 signature
288
*/
289
function _validateSignature(bytes32 hash, bytes calldata signature) internal view returns (bool);
290
}
291
```
292
293
#### RSA Signer
294
295
```solidity { .api }
296
/**
297
* @dev RSA signature verification signer
298
*/
299
abstract contract SignerRSAUpgradeable {
300
function __SignerRSA_init(bytes memory e, bytes memory n) internal onlyInitializing;
301
302
/**
303
* @dev Sets the RSA public key (exponent and modulus)
304
*/
305
function _setSigner(bytes memory e, bytes memory n) internal;
306
307
/**
308
* @dev Validates an RSA signature
309
*/
310
function _validateSignature(bytes32 hash, bytes calldata signature) internal view returns (bool);
311
}
312
```
313
314
#### ERC-7913 Signer
315
316
```solidity { .api }
317
/**
318
* @dev ERC-7913 standard signature verification signer
319
*/
320
abstract contract SignerERC7913Upgradeable {
321
function __SignerERC7913_init(bytes memory data) internal onlyInitializing;
322
323
/**
324
* @dev Sets the ERC-7913 signer data
325
*/
326
function _setSigner(bytes memory data) internal;
327
328
/**
329
* @dev Validates an ERC-7913 signature
330
*/
331
function _validateSignature(bytes32 hash, bytes calldata signature) internal view returns (bool);
332
}
333
```
334
335
#### Multi-Signature ERC-7913
336
337
```solidity { .api }
338
/**
339
* @dev Multi-signature verification using ERC-7913
340
*/
341
abstract contract MultiSignerERC7913Upgradeable {
342
function __MultiSignerERC7913_init(bytes[] memory signers) internal onlyInitializing;
343
344
/**
345
* @dev Sets multiple ERC-7913 signers
346
*/
347
function _setSigners(bytes[] memory signers) internal;
348
349
/**
350
* @dev Validates multiple signatures
351
*/
352
function _validateSignature(bytes32 hash, bytes calldata signature) internal view returns (bool);
353
}
354
355
/**
356
* @dev Weighted multi-signature verification using ERC-7913
357
*/
358
abstract contract MultiSignerERC7913WeightedUpgradeable {
359
function __MultiSignerERC7913Weighted_init(bytes[] memory signers, uint256[] memory weights, uint256 threshold) internal onlyInitializing;
360
361
/**
362
* @dev Sets weighted signers and threshold
363
*/
364
function _setSigners(bytes[] memory signers, uint256[] memory weights, uint256 threshold) internal;
365
366
/**
367
* @dev Validates weighted signatures against threshold
368
*/
369
function _validateSignature(bytes32 hash, bytes calldata signature) internal view returns (bool);
370
}
371
```
372
373
#### Draft ERC-7739
374
375
```solidity { .api }
376
/**
377
* @dev Draft ERC-7739 implementation for advanced signature schemes
378
*/
379
abstract contract ERC7739Upgradeable {
380
function __ERC7739_init(bytes memory config) internal onlyInitializing;
381
382
/**
383
* @dev Validates ERC-7739 signatures
384
*/
385
function _validateSignature(bytes32 hash, bytes calldata signature) internal view returns (bool);
386
}
387
```
388
389
### Context Utilities
390
391
Base context functionality for message handling.
392
393
```solidity { .api }
394
/**
395
* @dev Provides information about the current execution context
396
*/
397
abstract contract ContextUpgradeable {
398
function __Context_init() internal onlyInitializing;
399
400
/**
401
* @dev Returns the sender of the transaction
402
*/
403
function _msgSender() internal view returns (address);
404
405
/**
406
* @dev Returns the call data
407
*/
408
function _msgData() internal view returns (bytes calldata);
409
410
/**
411
* @dev Returns the length of the context suffix
412
*/
413
function _contextSuffixLength() internal view returns (uint256);
414
}
415
```
416
417
## Usage Examples
418
419
### Secure Token with Multiple Protections
420
421
```solidity
422
import {ERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
423
import {PausableUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/PausableUpgradeable.sol";
424
import {ReentrancyGuardUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol";
425
import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
426
427
contract SecureToken is ERC20Upgradeable, PausableUpgradeable, ReentrancyGuardUpgradeable, OwnableUpgradeable {
428
function initialize(address initialOwner) initializer public {
429
__ERC20_init("SecureToken", "STK");
430
__Pausable_init();
431
__ReentrancyGuard_init();
432
__Ownable_init(initialOwner);
433
}
434
435
function mint(address to, uint256 amount) public onlyOwner whenNotPaused {
436
_mint(to, amount);
437
}
438
439
function transfer(address to, uint256 amount) public override whenNotPaused nonReentrant returns (bool) {
440
return super.transfer(to, amount);
441
}
442
443
function pause() public onlyOwner {
444
_pause();
445
}
446
447
function unpause() public onlyOwner {
448
_unpause();
449
}
450
}
451
```
452
453
### Multicall Integration
454
455
```solidity
456
import {MulticallUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/MulticallUpgradeable.sol";
457
458
contract BatchOperations is MulticallUpgradeable, OwnableUpgradeable {
459
function initialize(address initialOwner) initializer public {
460
__Multicall_init();
461
__Ownable_init(initialOwner);
462
}
463
464
function setValues(uint256[] calldata ids, uint256[] calldata values) external onlyOwner {
465
require(ids.length == values.length, "Length mismatch");
466
for (uint256 i = 0; i < ids.length; i++) {
467
// Set values
468
}
469
}
470
471
// Users can batch multiple setValues calls in one transaction using multicall
472
}
473
```
474
475
### EIP-712 Signature Verification
476
477
```solidity
478
import {EIP712Upgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/EIP712Upgradeable.sol";
479
import {ECDSAUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/ECDSAUpgradeable.sol";
480
import {NoncesUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/NoncesUpgradeable.sol";
481
482
contract SignatureVerifier is EIP712Upgradeable, NoncesUpgradeable {
483
bytes32 private constant PERMIT_TYPEHASH = keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)");
484
485
function initialize() initializer public {
486
__EIP712_init("SignatureVerifier", "1");
487
__Nonces_init();
488
}
489
490
function permit(
491
address owner,
492
address spender,
493
uint256 value,
494
uint256 deadline,
495
uint8 v,
496
bytes32 r,
497
bytes32 s
498
) external {
499
require(block.timestamp <= deadline, "Permit expired");
500
501
bytes32 structHash = keccak256(abi.encode(
502
PERMIT_TYPEHASH,
503
owner,
504
spender,
505
value,
506
_useNonce(owner),
507
deadline
508
));
509
510
bytes32 hash = _hashTypedDataV4(structHash);
511
address signer = ECDSAUpgradeable.recover(hash, v, r, s);
512
require(signer == owner, "Invalid signature");
513
514
// Process permit
515
}
516
}
517
```