0
# Security Utilities
1
2
OpenZeppelin provides essential security utilities including safe mathematical operations, address utilities, reentrancy protection, and emergency pause functionality to prevent common vulnerabilities in smart contracts.
3
4
## Capabilities
5
6
### SafeMath - Overflow Protection
7
8
Library that provides mathematical functions that revert on overflow and underflow, replacing the built-in arithmetic operations.
9
10
```solidity { .api }
11
/**
12
* Mathematical functions with safety checks that revert on error
13
*/
14
library SafeMath {
15
/**
16
* Returns the addition of two unsigned integers, with an overflow flag
17
*/
18
function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256);
19
20
/**
21
* Returns the substraction of two unsigned integers, with an overflow flag
22
*/
23
function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256);
24
25
/**
26
* Returns the multiplication of two unsigned integers, with an overflow flag
27
*/
28
function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256);
29
30
/**
31
* Returns the division of two unsigned integers, with a division by zero flag
32
*/
33
function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256);
34
35
/**
36
* Returns the remainder of dividing two unsigned integers, with a division by zero flag
37
*/
38
function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256);
39
40
/**
41
* Returns the addition of two numbers, reverts on overflow
42
*/
43
function add(uint256 a, uint256 b) internal pure returns (uint256);
44
45
/**
46
* Returns the subtraction of two numbers, reverts on underflow
47
*/
48
function sub(uint256 a, uint256 b) internal pure returns (uint256);
49
50
/**
51
* Returns the multiplication of two numbers, reverts on overflow
52
*/
53
function mul(uint256 a, uint256 b) internal pure returns (uint256);
54
55
/**
56
* Returns the integer division of two numbers, reverts on division by zero
57
*/
58
function div(uint256 a, uint256 b) internal pure returns (uint256);
59
60
/**
61
* Returns the remainder of dividing two numbers, reverts with custom message on division by zero
62
*/
63
function mod(uint256 a, uint256 b) internal pure returns (uint256);
64
65
/**
66
* Same as add, but with a custom error message
67
*/
68
function add(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256);
69
70
/**
71
* Same as sub, but with a custom error message
72
*/
73
function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256);
74
75
/**
76
* Same as div, but with a custom error message
77
*/
78
function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256);
79
80
/**
81
* Same as mod, but with a custom error message
82
*/
83
function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256);
84
}
85
```
86
87
**Usage Example:**
88
89
```solidity
90
import "@openzeppelin/contracts/utils/math/SafeMath.sol";
91
92
contract MyContract {
93
using SafeMath for uint256;
94
95
function safeCalculation(uint256 a, uint256 b) public pure returns (uint256) {
96
return a.add(b).mul(2);
97
}
98
}
99
```
100
101
### Math - General Mathematical Operations
102
103
Standard mathematical utilities for common operations.
104
105
```solidity { .api }
106
/**
107
* Standard math utilities missing in the Solidity language
108
*/
109
library Math {
110
/**
111
* Returns the largest of two numbers
112
*/
113
function max(uint256 a, uint256 b) internal pure returns (uint256);
114
115
/**
116
* Returns the smallest of two numbers
117
*/
118
function min(uint256 a, uint256 b) internal pure returns (uint256);
119
120
/**
121
* Returns the average of two numbers. The result is rounded towards zero
122
*/
123
function average(uint256 a, uint256 b) internal pure returns (uint256);
124
125
/**
126
* Returns the ceiling of the division of two numbers
127
*/
128
function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256);
129
}
130
```
131
132
### SignedSafeMath - Signed Integer Safety
133
134
Safe math operations for signed integers.
135
136
```solidity { .api }
137
/**
138
* Mathematical functions for signed integers with safety checks that revert on error
139
*/
140
library SignedSafeMath {
141
/**
142
* Returns the multiplication of two signed integers, reverts on overflow
143
*/
144
function mul(int256 a, int256 b) internal pure returns (int256);
145
146
/**
147
* Returns the integer division of two signed integers, reverts on division by zero
148
*/
149
function div(int256 a, int256 b) internal pure returns (int256);
150
151
/**
152
* Returns the subtraction of two signed integers, reverts on overflow
153
*/
154
function sub(int256 a, int256 b) internal pure returns (int256);
155
156
/**
157
* Returns the addition of two signed integers, reverts on overflow
158
*/
159
function add(int256 a, int256 b) internal pure returns (int256);
160
}
161
```
162
163
### Address - Address Utilities
164
165
Collection of functions related to the address type and low-level calls.
166
167
```solidity { .api }
168
/**
169
* Collection of functions related to the address type
170
*/
171
library Address {
172
/**
173
* Returns true if account is a contract
174
*/
175
function isContract(address account) internal view returns (bool);
176
177
/**
178
* Replacement for Solidity's transfer: sends amount wei to recipient, forwarding all available gas and reverting on errors
179
*/
180
function sendValue(address payable recipient, uint256 amount) internal;
181
182
/**
183
* Performs a Solidity function call using a low level call
184
*/
185
function functionCall(address target, bytes memory data) internal returns (bytes memory);
186
187
/**
188
* Same as functionCall, but with errorMessage as a fallback revert reason
189
*/
190
function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory);
191
192
/**
193
* Same as functionCall, but also transferring value wei to target
194
*/
195
function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory);
196
197
/**
198
* Same as functionCallWithValue, but with errorMessage as a fallback revert reason
199
*/
200
function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory);
201
202
/**
203
* Same as functionCall, but performing a static call
204
*/
205
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory);
206
207
/**
208
* Same as functionStaticCall, but with errorMessage as a fallback revert reason
209
*/
210
function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory);
211
212
/**
213
* Same as functionCall, but performing a delegate call
214
*/
215
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory);
216
217
/**
218
* Same as functionDelegateCall, but with errorMessage as a fallback revert reason
219
*/
220
function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory);
221
}
222
```
223
224
### ReentrancyGuard - Reentrancy Protection
225
226
Contract module that helps prevent reentrant calls to a function.
227
228
```solidity { .api }
229
/**
230
* Contract module that helps prevent reentrant calls to a function
231
*/
232
abstract contract ReentrancyGuard {
233
/**
234
* Prevents a contract from calling itself, directly or indirectly
235
*/
236
modifier nonReentrant();
237
}
238
```
239
240
**Usage Example:**
241
242
```solidity
243
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
244
245
contract MyContract is ReentrancyGuard {
246
mapping(address => uint256) private balances;
247
248
function withdraw() public nonReentrant {
249
uint256 amount = balances[msg.sender];
250
balances[msg.sender] = 0;
251
(bool success, ) = msg.sender.call{value: amount}("");
252
require(success, "Transfer failed");
253
}
254
}
255
```
256
257
### Pausable - Emergency Stop
258
259
Contract module which allows children to implement an emergency stop mechanism that can be triggered by an authorized account.
260
261
```solidity { .api }
262
/**
263
* Contract module which allows children to implement an emergency stop mechanism
264
*/
265
abstract contract Pausable is Context {
266
/**
267
* Returns true if the contract is paused, and false otherwise
268
*/
269
function paused() public view virtual returns (bool);
270
271
/**
272
* Modifier to make a function callable only when the contract is not paused
273
*/
274
modifier whenNotPaused();
275
276
/**
277
* Modifier to make a function callable only when the contract is paused
278
*/
279
modifier whenPaused();
280
281
/**
282
* Triggers stopped state
283
*/
284
function _pause() internal virtual whenNotPaused;
285
286
/**
287
* Returns to normal state
288
*/
289
function _unpause() internal virtual whenPaused;
290
291
/**
292
* Emitted when the pause is triggered by account
293
*/
294
event Paused(address account);
295
296
/**
297
* Emitted when the pause is lifted by account
298
*/
299
event Unpaused(address account);
300
}
301
```
302
303
**Usage Example:**
304
305
```solidity
306
import "@openzeppelin/contracts/security/Pausable.sol";
307
import "@openzeppelin/contracts/access/Ownable.sol";
308
309
contract MyContract is Pausable, Ownable {
310
function pause() public onlyOwner {
311
_pause();
312
}
313
314
function unpause() public onlyOwner {
315
_unpause();
316
}
317
318
function normalOperation() public whenNotPaused {
319
// This function can only be called when not paused
320
}
321
322
function emergencyOperation() public whenPaused {
323
// This function can only be called when paused
324
}
325
}
326
```
327
328
### SafeCast - Type Casting Safety
329
330
Library of safe casting functions that revert on overflow.
331
332
```solidity { .api }
333
/**
334
* Wrappers over Solidity's uintXX/intXX casting operators with added overflow checks
335
*/
336
library SafeCast {
337
/**
338
* Converts a uint256 to uint248, reverting on overflow
339
*/
340
function toUint248(uint256 value) internal pure returns (uint248);
341
342
/**
343
* Converts a uint256 to uint240, reverting on overflow
344
*/
345
function toUint240(uint256 value) internal pure returns (uint240);
346
347
/**
348
* Converts a uint256 to uint128, reverting on overflow
349
*/
350
function toUint128(uint256 value) internal pure returns (uint128);
351
352
/**
353
* Converts a uint256 to uint96, reverting on overflow
354
*/
355
function toUint96(uint256 value) internal pure returns (uint96);
356
357
/**
358
* Converts a uint256 to uint64, reverting on overflow
359
*/
360
function toUint64(uint256 value) internal pure returns (uint64);
361
362
/**
363
* Converts a uint256 to uint32, reverting on overflow
364
*/
365
function toUint32(uint256 value) internal pure returns (uint32);
366
367
/**
368
* Converts a uint256 to uint16, reverting on overflow
369
*/
370
function toUint16(uint256 value) internal pure returns (uint16);
371
372
/**
373
* Converts a uint256 to uint8, reverting on overflow
374
*/
375
function toUint8(uint256 value) internal pure returns (uint8);
376
377
/**
378
* Converts a signed int256 into an unsigned uint256
379
*/
380
function toUint256(int256 value) internal pure returns (uint256);
381
382
/**
383
* Converts a uint256 into a signed int256
384
*/
385
function toInt256(uint256 value) internal pure returns (int256);
386
}
387
```
388
389
### Context - Execution Context
390
391
Provides information about the current execution context, including the sender of the transaction and its data.
392
393
```solidity { .api }
394
/**
395
* Provides information about the current execution context
396
*/
397
abstract contract Context {
398
/**
399
* Returns the address of the account that initiated the transaction
400
*/
401
function _msgSender() internal view virtual returns (address);
402
403
/**
404
* Returns the calldata of the transaction
405
*/
406
function _msgData() internal view virtual returns (bytes calldata);
407
}
408
```
409
410
## Utility Libraries
411
412
### Counters - Safe Counter Operations
413
414
```solidity { .api }
415
/**
416
* Provides counters that can only be incremented, decremented or reset
417
*/
418
library Counters {
419
struct Counter {
420
uint256 _value;
421
}
422
423
/**
424
* Returns the current value of the counter
425
*/
426
function current(Counter storage counter) internal view returns (uint256);
427
428
/**
429
* Increments the counter by 1
430
*/
431
function increment(Counter storage counter) internal;
432
433
/**
434
* Decrements the counter by 1, reverting if result would be negative
435
*/
436
function decrement(Counter storage counter) internal;
437
438
/**
439
* Resets the counter to 0
440
*/
441
function reset(Counter storage counter) internal;
442
}
443
```
444
445
### Strings - String Operations
446
447
```solidity { .api }
448
/**
449
* String operations
450
*/
451
library Strings {
452
/**
453
* Converts a uint256 to its ASCII string decimal representation
454
*/
455
function toString(uint256 value) internal pure returns (string memory);
456
}
457
```
458
459
### Arrays - Array Utilities
460
461
```solidity { .api }
462
/**
463
* Collection of functions related to array types
464
*/
465
library Arrays {
466
/**
467
* Searches a sorted array and returns the first index that contains a value greater or equal to element
468
*/
469
function findUpperBound(uint256[] storage array, uint256 element) internal view returns (uint256);
470
}
471
```
472
473
### EnumerableSet - Gas-Efficient Set Data Structure
474
475
```solidity { .api }
476
/**
477
* Library for managing sets of primitive types
478
*/
479
library EnumerableSet {
480
struct Bytes32Set {
481
bytes32[] _values;
482
mapping(bytes32 => uint256) _indexes;
483
}
484
485
struct AddressSet {
486
bytes32[] _values;
487
mapping(bytes32 => uint256) _indexes;
488
}
489
490
struct UintSet {
491
bytes32[] _values;
492
mapping(bytes32 => uint256) _indexes;
493
}
494
495
// Bytes32Set functions
496
function add(Bytes32Set storage set, bytes32 value) internal returns (bool);
497
function remove(Bytes32Set storage set, bytes32 value) internal returns (bool);
498
function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool);
499
function length(Bytes32Set storage set) internal view returns (uint256);
500
function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32);
501
function values(Bytes32Set storage set) internal view returns (bytes32[] memory);
502
503
// AddressSet functions
504
function add(AddressSet storage set, address value) internal returns (bool);
505
function remove(AddressSet storage set, address value) internal returns (bool);
506
function contains(AddressSet storage set, address value) internal view returns (bool);
507
function length(AddressSet storage set) internal view returns (uint256);
508
function at(AddressSet storage set, uint256 index) internal view returns (address);
509
function values(AddressSet storage set) internal view returns (address[] memory);
510
511
// UintSet functions
512
function add(UintSet storage set, uint256 value) internal returns (bool);
513
function remove(UintSet storage set, uint256 value) internal returns (bool);
514
function contains(UintSet storage set, uint256 value) internal view returns (bool);
515
function length(UintSet storage set) internal view returns (uint256);
516
function at(UintSet storage set, uint256 index) internal view returns (uint256);
517
function values(UintSet storage set) internal view returns (uint256[] memory);
518
}
519
```
520
521
**Usage Example:**
522
523
```solidity
524
import "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
525
526
contract MembershipManager {
527
using EnumerableSet for EnumerableSet.AddressSet;
528
529
EnumerableSet.AddressSet private members;
530
531
function addMember(address member) external {
532
require(members.add(member), "Member already exists");
533
}
534
535
function removeMember(address member) external {
536
require(members.remove(member), "Member does not exist");
537
}
538
539
function isMember(address member) external view returns (bool) {
540
return members.contains(member);
541
}
542
543
function getMemberCount() external view returns (uint256) {
544
return members.length();
545
}
546
547
function getMemberAt(uint256 index) external view returns (address) {
548
return members.at(index);
549
}
550
551
function getAllMembers() external view returns (address[] memory) {
552
return members.values();
553
}
554
}
555
```
556
557
### EnumerableMap - Gas-Efficient Map Data Structure
558
559
```solidity { .api }
560
/**
561
* Library for managing an enumerable variant of Solidity's mapping type
562
*/
563
library EnumerableMap {
564
struct UintToAddressMap {
565
EnumerableSet.Bytes32Set _keys;
566
mapping(bytes32 => bytes32) _values;
567
}
568
569
/**
570
* Adds a key-value pair to a map, or updates the value for an existing key
571
*/
572
function set(UintToAddressMap storage map, uint256 key, address value) internal returns (bool);
573
574
/**
575
* Removes a value from a set
576
*/
577
function remove(UintToAddressMap storage map, uint256 key) internal returns (bool);
578
579
/**
580
* Returns true if the key is in the map
581
*/
582
function contains(UintToAddressMap storage map, uint256 key) internal view returns (bool);
583
584
/**
585
* Returns the number of elements in the map
586
*/
587
function length(UintToAddressMap storage map) internal view returns (uint256);
588
589
/**
590
* Returns the element stored at position index in the set
591
*/
592
function at(UintToAddressMap storage map, uint256 index) internal view returns (uint256, address);
593
594
/**
595
* Tries to returns the value associated with key
596
*/
597
function tryGet(UintToAddressMap storage map, uint256 key) internal view returns (bool, address);
598
599
/**
600
* Returns the value associated with key
601
*/
602
function get(UintToAddressMap storage map, uint256 key) internal view returns (address);
603
}
604
```
605
606
**Usage Example:**
607
608
```solidity
609
import "@openzeppelin/contracts/utils/structs/EnumerableMap.sol";
610
611
contract TokenRegistry {
612
using EnumerableMap for EnumerableMap.UintToAddressMap;
613
614
EnumerableMap.UintToAddressMap private tokenMap;
615
616
function registerToken(uint256 tokenId, address tokenAddress) external {
617
tokenMap.set(tokenId, tokenAddress);
618
}
619
620
function removeToken(uint256 tokenId) external {
621
tokenMap.remove(tokenId);
622
}
623
624
function getTokenAddress(uint256 tokenId) external view returns (address) {
625
return tokenMap.get(tokenId);
626
}
627
628
function tokenExists(uint256 tokenId) external view returns (bool) {
629
return tokenMap.contains(tokenId);
630
}
631
632
function getTokenCount() external view returns (uint256) {
633
return tokenMap.length();
634
}
635
636
function getTokenAtIndex(uint256 index) external view returns (uint256, address) {
637
return tokenMap.at(index);
638
}
639
}
640
```
641
642
## Security Best Practices
643
644
### Complete Security Example
645
646
```solidity
647
pragma solidity ^0.8.0;
648
649
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
650
import "@openzeppelin/contracts/security/Pausable.sol";
651
import "@openzeppelin/contracts/access/Ownable.sol";
652
import "@openzeppelin/contracts/utils/math/SafeMath.sol";
653
import "@openzeppelin/contracts/utils/Address.sol";
654
655
contract SecureContract is ReentrancyGuard, Pausable, Ownable {
656
using SafeMath for uint256;
657
using Address for address payable;
658
659
mapping(address => uint256) private balances;
660
uint256 public totalDeposits;
661
662
event Deposit(address indexed user, uint256 amount);
663
event Withdrawal(address indexed user, uint256 amount);
664
665
function deposit() public payable whenNotPaused {
666
require(msg.value > 0, "Deposit must be greater than 0");
667
668
balances[msg.sender] = balances[msg.sender].add(msg.value);
669
totalDeposits = totalDeposits.add(msg.value);
670
671
emit Deposit(msg.sender, msg.value);
672
}
673
674
function withdraw(uint256 amount) public nonReentrant whenNotPaused {
675
require(amount > 0, "Withdrawal must be greater than 0");
676
require(balances[msg.sender] >= amount, "Insufficient balance");
677
678
balances[msg.sender] = balances[msg.sender].sub(amount);
679
totalDeposits = totalDeposits.sub(amount);
680
681
payable(msg.sender).sendValue(amount);
682
683
emit Withdrawal(msg.sender, amount);
684
}
685
686
function emergencyPause() public onlyOwner {
687
_pause();
688
}
689
690
function unpause() public onlyOwner {
691
_unpause();
692
}
693
694
function getBalance(address user) public view returns (uint256) {
695
return balances[user];
696
}
697
}
698
```