@theqrl/qrl-contracts 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,552 @@
1
+ // SPDX-License-Identifier: MIT
2
+ // QRL Contracts (last updated v0.1.0) (utils/Arrays.hyp)
3
+ // This file was procedurally generated from scripts/generate/templates/Arrays.js.
4
+
5
+ pragma hyperion >=0.0;
6
+
7
+ import {Comparators} from "./Comparators.hyp";
8
+ import {SlotDerivation} from "./SlotDerivation.hyp";
9
+ import {StorageSlot} from "./StorageSlot.hyp";
10
+ import {Math} from "./math/Math.hyp";
11
+
12
+ /**
13
+ * @dev Collection of functions related to array types.
14
+ */
15
+ library Arrays {
16
+ using SlotDerivation for bytes32;
17
+ using StorageSlot for bytes32;
18
+
19
+ /**
20
+ * @dev Sort an array of uint256 (in memory) following the provided comparator function.
21
+ *
22
+ * This function does the sorting "in place", meaning that it overrides the input. The object is returned for
23
+ * convenience, but that returned value can be discarded safely if the caller has a memory pointer to the array.
24
+ *
25
+ * NOTE: this function's cost is `O(n · log(n))` in average and `O(n²)` in the worst case, with n the length of the
26
+ * array. Using it in view functions that are executed through `eth_call` is safe, but one should be very careful
27
+ * when executing this as part of a transaction. If the array being sorted is too large, the sort operation may
28
+ * consume more gas than is available in a block, leading to potential DoS.
29
+ *
30
+ * IMPORTANT: Consider memory side-effects when using custom comparator functions that access memory in an unsafe way.
31
+ */
32
+ function sort(
33
+ uint256[] memory array,
34
+ function(uint256, uint256) pure returns (bool) comp
35
+ ) internal pure returns (uint256[] memory) {
36
+ _quickSort(_begin(array), _end(array), comp);
37
+ return array;
38
+ }
39
+
40
+ /**
41
+ * @dev Variant of {sort} that sorts an array of uint256 in increasing order.
42
+ */
43
+ function sort(uint256[] memory array) internal pure returns (uint256[] memory) {
44
+ sort(array, Comparators.lt);
45
+ return array;
46
+ }
47
+
48
+ /**
49
+ * @dev Sort an array of address (in memory) following the provided comparator function.
50
+ *
51
+ * This function does the sorting "in place", meaning that it overrides the input. The object is returned for
52
+ * convenience, but that returned value can be discarded safely if the caller has a memory pointer to the array.
53
+ *
54
+ * NOTE: this function's cost is `O(n · log(n))` in average and `O(n²)` in the worst case, with n the length of the
55
+ * array. Using it in view functions that are executed through `eth_call` is safe, but one should be very careful
56
+ * when executing this as part of a transaction. If the array being sorted is too large, the sort operation may
57
+ * consume more gas than is available in a block, leading to potential DoS.
58
+ *
59
+ * IMPORTANT: Consider memory side-effects when using custom comparator functions that access memory in an unsafe way.
60
+ */
61
+ function sort(
62
+ address[] memory array,
63
+ function(address, address) pure returns (bool) comp
64
+ ) internal pure returns (address[] memory) {
65
+ sort(_castToUint256Array(array), _castToUint256Comp(comp));
66
+ return array;
67
+ }
68
+
69
+ /**
70
+ * @dev Variant of {sort} that sorts an array of address in increasing order.
71
+ */
72
+ function sort(address[] memory array) internal pure returns (address[] memory) {
73
+ sort(_castToUint256Array(array), Comparators.lt);
74
+ return array;
75
+ }
76
+
77
+ /**
78
+ * @dev Sort an array of bytes32 (in memory) following the provided comparator function.
79
+ *
80
+ * This function does the sorting "in place", meaning that it overrides the input. The object is returned for
81
+ * convenience, but that returned value can be discarded safely if the caller has a memory pointer to the array.
82
+ *
83
+ * NOTE: this function's cost is `O(n · log(n))` in average and `O(n²)` in the worst case, with n the length of the
84
+ * array. Using it in view functions that are executed through `eth_call` is safe, but one should be very careful
85
+ * when executing this as part of a transaction. If the array being sorted is too large, the sort operation may
86
+ * consume more gas than is available in a block, leading to potential DoS.
87
+ *
88
+ * IMPORTANT: Consider memory side-effects when using custom comparator functions that access memory in an unsafe way.
89
+ */
90
+ function sort(
91
+ bytes32[] memory array,
92
+ function(bytes32, bytes32) pure returns (bool) comp
93
+ ) internal pure returns (bytes32[] memory) {
94
+ sort(_castToUint256Array(array), _castToUint256Comp(comp));
95
+ return array;
96
+ }
97
+
98
+ /**
99
+ * @dev Variant of {sort} that sorts an array of bytes32 in increasing order.
100
+ */
101
+ function sort(bytes32[] memory array) internal pure returns (bytes32[] memory) {
102
+ sort(_castToUint256Array(array), Comparators.lt);
103
+ return array;
104
+ }
105
+
106
+ /**
107
+ * @dev Performs a quick sort of a segment of memory. The segment sorted starts at `begin` (inclusive), and stops
108
+ * at end (exclusive). Sorting follows the `comp` comparator.
109
+ *
110
+ * Invariant: `begin <= end`. This is the case when initially called by {sort} and is preserved in subcalls.
111
+ *
112
+ * IMPORTANT: Memory locations between `begin` and `end` are not validated/zeroed. This function should
113
+ * be used only if the limits are within a memory array.
114
+ */
115
+ function _quickSort(uint256 begin, uint256 end, function(uint256, uint256) pure returns (bool) comp) private pure {
116
+ unchecked {
117
+ if (end - begin < 0x40) return;
118
+
119
+ // Use first element as pivot
120
+ uint256 pivot = _mload(begin);
121
+ // Position where the pivot should be at the end of the loop
122
+ uint256 pos = begin;
123
+
124
+ for (uint256 it = begin + 0x20; it < end; it += 0x20) {
125
+ if (comp(_mload(it), pivot)) {
126
+ // If the value stored at the iterator's position comes before the pivot, we increment the
127
+ // position of the pivot and move the value there.
128
+ pos += 0x20;
129
+ _swap(pos, it);
130
+ }
131
+ }
132
+
133
+ _swap(begin, pos); // Swap pivot into place
134
+ _quickSort(begin, pos, comp); // Sort the left side of the pivot
135
+ _quickSort(pos + 0x20, end, comp); // Sort the right side of the pivot
136
+ }
137
+ }
138
+
139
+ /**
140
+ * @dev Pointer to the memory location of the first element of `array`.
141
+ */
142
+ function _begin(uint256[] memory array) private pure returns (uint256 ptr) {
143
+ assembly ("memory-safe") {
144
+ ptr := add(array, 0x20)
145
+ }
146
+ }
147
+
148
+ /**
149
+ * @dev Pointer to the memory location of the first memory word (32bytes) after `array`. This is the memory word
150
+ * that comes just after the last element of the array.
151
+ */
152
+ function _end(uint256[] memory array) private pure returns (uint256 ptr) {
153
+ unchecked {
154
+ return _begin(array) + array.length * 0x20;
155
+ }
156
+ }
157
+
158
+ /**
159
+ * @dev Load memory word (as a uint256) at location `ptr`.
160
+ */
161
+ function _mload(uint256 ptr) private pure returns (uint256 value) {
162
+ assembly {
163
+ value := mload(ptr)
164
+ }
165
+ }
166
+
167
+ /**
168
+ * @dev Swaps the elements memory location `ptr1` and `ptr2`.
169
+ */
170
+ function _swap(uint256 ptr1, uint256 ptr2) private pure {
171
+ assembly {
172
+ let value1 := mload(ptr1)
173
+ let value2 := mload(ptr2)
174
+ mstore(ptr1, value2)
175
+ mstore(ptr2, value1)
176
+ }
177
+ }
178
+
179
+ /// @dev Helper: low level cast address memory array to uint256 memory array
180
+ function _castToUint256Array(address[] memory input) private pure returns (uint256[] memory output) {
181
+ assembly {
182
+ output := input
183
+ }
184
+ }
185
+
186
+ /// @dev Helper: low level cast bytes32 memory array to uint256 memory array
187
+ function _castToUint256Array(bytes32[] memory input) private pure returns (uint256[] memory output) {
188
+ assembly {
189
+ output := input
190
+ }
191
+ }
192
+
193
+ /// @dev Helper: low level cast address comp function to uint256 comp function
194
+ function _castToUint256Comp(
195
+ function(address, address) pure returns (bool) input
196
+ ) private pure returns (function(uint256, uint256) pure returns (bool) output) {
197
+ assembly {
198
+ output := input
199
+ }
200
+ }
201
+
202
+ /// @dev Helper: low level cast bytes32 comp function to uint256 comp function
203
+ function _castToUint256Comp(
204
+ function(bytes32, bytes32) pure returns (bool) input
205
+ ) private pure returns (function(uint256, uint256) pure returns (bool) output) {
206
+ assembly {
207
+ output := input
208
+ }
209
+ }
210
+
211
+ /**
212
+ * @dev Searches a sorted `array` and returns the first index that contains
213
+ * a value greater or equal to `element`. If no such index exists (i.e. all
214
+ * values in the array are strictly less than `element`), the array length is
215
+ * returned. Time complexity O(log n).
216
+ *
217
+ * NOTE: The `array` is expected to be sorted in ascending order, and to
218
+ * contain no repeated elements.
219
+ *
220
+ * IMPORTANT: Deprecated. This implementation behaves as {lowerBound} but lacks
221
+ * support for repeated elements in the array. The {lowerBound} function should
222
+ * be used instead.
223
+ */
224
+ function findUpperBound(uint256[] storage array, uint256 element) internal view returns (uint256) {
225
+ uint256 low = 0;
226
+ uint256 high = array.length;
227
+
228
+ if (high == 0) {
229
+ return 0;
230
+ }
231
+
232
+ while (low < high) {
233
+ uint256 mid = Math.average(low, high);
234
+
235
+ // Note that mid will always be strictly less than high (i.e. it will be a valid array index)
236
+ // because Math.average rounds towards zero (it does integer division with truncation).
237
+ if (unsafeAccess(array, mid).value > element) {
238
+ high = mid;
239
+ } else {
240
+ low = mid + 1;
241
+ }
242
+ }
243
+
244
+ // At this point `low` is the exclusive upper bound. We will return the inclusive upper bound.
245
+ if (low > 0 && unsafeAccess(array, low - 1).value == element) {
246
+ return low - 1;
247
+ } else {
248
+ return low;
249
+ }
250
+ }
251
+
252
+ /**
253
+ * @dev Searches an `array` sorted in ascending order and returns the first
254
+ * index that contains a value greater or equal than `element`. If no such index
255
+ * exists (i.e. all values in the array are strictly less than `element`), the array
256
+ * length is returned. Time complexity O(log n).
257
+ *
258
+ * See C++'s https://en.cppreference.com/w/cpp/algorithm/lower_bound[lower_bound].
259
+ */
260
+ function lowerBound(uint256[] storage array, uint256 element) internal view returns (uint256) {
261
+ uint256 low = 0;
262
+ uint256 high = array.length;
263
+
264
+ if (high == 0) {
265
+ return 0;
266
+ }
267
+
268
+ while (low < high) {
269
+ uint256 mid = Math.average(low, high);
270
+
271
+ // Note that mid will always be strictly less than high (i.e. it will be a valid array index)
272
+ // because Math.average rounds towards zero (it does integer division with truncation).
273
+ if (unsafeAccess(array, mid).value < element) {
274
+ // this cannot overflow because mid < high
275
+ unchecked {
276
+ low = mid + 1;
277
+ }
278
+ } else {
279
+ high = mid;
280
+ }
281
+ }
282
+
283
+ return low;
284
+ }
285
+
286
+ /**
287
+ * @dev Searches an `array` sorted in ascending order and returns the first
288
+ * index that contains a value strictly greater than `element`. If no such index
289
+ * exists (i.e. all values in the array are strictly less than `element`), the array
290
+ * length is returned. Time complexity O(log n).
291
+ *
292
+ * See C++'s https://en.cppreference.com/w/cpp/algorithm/upper_bound[upper_bound].
293
+ */
294
+ function upperBound(uint256[] storage array, uint256 element) internal view returns (uint256) {
295
+ uint256 low = 0;
296
+ uint256 high = array.length;
297
+
298
+ if (high == 0) {
299
+ return 0;
300
+ }
301
+
302
+ while (low < high) {
303
+ uint256 mid = Math.average(low, high);
304
+
305
+ // Note that mid will always be strictly less than high (i.e. it will be a valid array index)
306
+ // because Math.average rounds towards zero (it does integer division with truncation).
307
+ if (unsafeAccess(array, mid).value > element) {
308
+ high = mid;
309
+ } else {
310
+ // this cannot overflow because mid < high
311
+ unchecked {
312
+ low = mid + 1;
313
+ }
314
+ }
315
+ }
316
+
317
+ return low;
318
+ }
319
+
320
+ /**
321
+ * @dev Same as {lowerBound}, but with an array in memory.
322
+ */
323
+ function lowerBoundMemory(uint256[] memory array, uint256 element) internal pure returns (uint256) {
324
+ uint256 low = 0;
325
+ uint256 high = array.length;
326
+
327
+ if (high == 0) {
328
+ return 0;
329
+ }
330
+
331
+ while (low < high) {
332
+ uint256 mid = Math.average(low, high);
333
+
334
+ // Note that mid will always be strictly less than high (i.e. it will be a valid array index)
335
+ // because Math.average rounds towards zero (it does integer division with truncation).
336
+ if (unsafeMemoryAccess(array, mid) < element) {
337
+ // this cannot overflow because mid < high
338
+ unchecked {
339
+ low = mid + 1;
340
+ }
341
+ } else {
342
+ high = mid;
343
+ }
344
+ }
345
+
346
+ return low;
347
+ }
348
+
349
+ /**
350
+ * @dev Same as {upperBound}, but with an array in memory.
351
+ */
352
+ function upperBoundMemory(uint256[] memory array, uint256 element) internal pure returns (uint256) {
353
+ uint256 low = 0;
354
+ uint256 high = array.length;
355
+
356
+ if (high == 0) {
357
+ return 0;
358
+ }
359
+
360
+ while (low < high) {
361
+ uint256 mid = Math.average(low, high);
362
+
363
+ // Note that mid will always be strictly less than high (i.e. it will be a valid array index)
364
+ // because Math.average rounds towards zero (it does integer division with truncation).
365
+ if (unsafeMemoryAccess(array, mid) > element) {
366
+ high = mid;
367
+ } else {
368
+ // this cannot overflow because mid < high
369
+ unchecked {
370
+ low = mid + 1;
371
+ }
372
+ }
373
+ }
374
+
375
+ return low;
376
+ }
377
+
378
+ /**
379
+ * @dev Access an array in an "unsafe" way. Skips hyperion "index-out-of-range" check.
380
+ *
381
+ * WARNING: Only use if you are certain `pos` is lower than the array length.
382
+ */
383
+ function unsafeAccess(address[] storage arr, uint256 pos) internal pure returns (StorageSlot.AddressSlot storage) {
384
+ bytes32 slot;
385
+ assembly ("memory-safe") {
386
+ slot := arr.slot
387
+ }
388
+ return slot.deriveArray().offset(pos).getAddressSlot();
389
+ }
390
+
391
+ /**
392
+ * @dev Access an array in an "unsafe" way. Skips hyperion "index-out-of-range" check.
393
+ *
394
+ * WARNING: Only use if you are certain `pos` is lower than the array length.
395
+ */
396
+ function unsafeAccess(bytes32[] storage arr, uint256 pos) internal pure returns (StorageSlot.Bytes32Slot storage) {
397
+ bytes32 slot;
398
+ assembly ("memory-safe") {
399
+ slot := arr.slot
400
+ }
401
+ return slot.deriveArray().offset(pos).getBytes32Slot();
402
+ }
403
+
404
+ /**
405
+ * @dev Access an array in an "unsafe" way. Skips hyperion "index-out-of-range" check.
406
+ *
407
+ * WARNING: Only use if you are certain `pos` is lower than the array length.
408
+ */
409
+ function unsafeAccess(uint256[] storage arr, uint256 pos) internal pure returns (StorageSlot.Uint256Slot storage) {
410
+ bytes32 slot;
411
+ assembly ("memory-safe") {
412
+ slot := arr.slot
413
+ }
414
+ return slot.deriveArray().offset(pos).getUint256Slot();
415
+ }
416
+
417
+ /**
418
+ * @dev Access an array in an "unsafe" way. Skips hyperion "index-out-of-range" check.
419
+ *
420
+ * WARNING: Only use if you are certain `pos` is lower than the array length.
421
+ */
422
+ function unsafeAccess(bytes[] storage arr, uint256 pos) internal pure returns (StorageSlot.BytesSlot storage) {
423
+ bytes32 slot;
424
+ assembly ("memory-safe") {
425
+ slot := arr.slot
426
+ }
427
+ return slot.deriveArray().offset(pos).getBytesSlot();
428
+ }
429
+
430
+ /**
431
+ * @dev Access an array in an "unsafe" way. Skips hyperion "index-out-of-range" check.
432
+ *
433
+ * WARNING: Only use if you are certain `pos` is lower than the array length.
434
+ */
435
+ function unsafeAccess(string[] storage arr, uint256 pos) internal pure returns (StorageSlot.StringSlot storage) {
436
+ bytes32 slot;
437
+ assembly ("memory-safe") {
438
+ slot := arr.slot
439
+ }
440
+ return slot.deriveArray().offset(pos).getStringSlot();
441
+ }
442
+
443
+ /**
444
+ * @dev Access an array in an "unsafe" way. Skips hyperion "index-out-of-range" check.
445
+ *
446
+ * WARNING: Only use if you are certain `pos` is lower than the array length.
447
+ */
448
+ function unsafeMemoryAccess(address[] memory arr, uint256 pos) internal pure returns (address res) {
449
+ assembly {
450
+ res := mload(add(add(arr, 0x20), mul(pos, 0x20)))
451
+ }
452
+ }
453
+
454
+ /**
455
+ * @dev Access an array in an "unsafe" way. Skips hyperion "index-out-of-range" check.
456
+ *
457
+ * WARNING: Only use if you are certain `pos` is lower than the array length.
458
+ */
459
+ function unsafeMemoryAccess(bytes32[] memory arr, uint256 pos) internal pure returns (bytes32 res) {
460
+ assembly {
461
+ res := mload(add(add(arr, 0x20), mul(pos, 0x20)))
462
+ }
463
+ }
464
+
465
+ /**
466
+ * @dev Access an array in an "unsafe" way. Skips hyperion "index-out-of-range" check.
467
+ *
468
+ * WARNING: Only use if you are certain `pos` is lower than the array length.
469
+ */
470
+ function unsafeMemoryAccess(uint256[] memory arr, uint256 pos) internal pure returns (uint256 res) {
471
+ assembly {
472
+ res := mload(add(add(arr, 0x20), mul(pos, 0x20)))
473
+ }
474
+ }
475
+
476
+ /**
477
+ * @dev Access an array in an "unsafe" way. Skips hyperion "index-out-of-range" check.
478
+ *
479
+ * WARNING: Only use if you are certain `pos` is lower than the array length.
480
+ */
481
+ function unsafeMemoryAccess(bytes[] memory arr, uint256 pos) internal pure returns (bytes memory res) {
482
+ assembly {
483
+ res := mload(add(add(arr, 0x20), mul(pos, 0x20)))
484
+ }
485
+ }
486
+
487
+ /**
488
+ * @dev Access an array in an "unsafe" way. Skips hyperion "index-out-of-range" check.
489
+ *
490
+ * WARNING: Only use if you are certain `pos` is lower than the array length.
491
+ */
492
+ function unsafeMemoryAccess(string[] memory arr, uint256 pos) internal pure returns (string memory res) {
493
+ assembly {
494
+ res := mload(add(add(arr, 0x20), mul(pos, 0x20)))
495
+ }
496
+ }
497
+
498
+ /**
499
+ * @dev Helper to set the length of a dynamic array. Directly writing to `.length` is forbidden.
500
+ *
501
+ * WARNING: this does not clear elements if length is reduced, of initialize elements if length is increased.
502
+ */
503
+ function unsafeSetLength(address[] storage array, uint256 len) internal {
504
+ assembly ("memory-safe") {
505
+ sstore(array.slot, len)
506
+ }
507
+ }
508
+
509
+ /**
510
+ * @dev Helper to set the length of a dynamic array. Directly writing to `.length` is forbidden.
511
+ *
512
+ * WARNING: this does not clear elements if length is reduced, of initialize elements if length is increased.
513
+ */
514
+ function unsafeSetLength(bytes32[] storage array, uint256 len) internal {
515
+ assembly ("memory-safe") {
516
+ sstore(array.slot, len)
517
+ }
518
+ }
519
+
520
+ /**
521
+ * @dev Helper to set the length of a dynamic array. Directly writing to `.length` is forbidden.
522
+ *
523
+ * WARNING: this does not clear elements if length is reduced, of initialize elements if length is increased.
524
+ */
525
+ function unsafeSetLength(uint256[] storage array, uint256 len) internal {
526
+ assembly ("memory-safe") {
527
+ sstore(array.slot, len)
528
+ }
529
+ }
530
+
531
+ /**
532
+ * @dev Helper to set the length of a dynamic array. Directly writing to `.length` is forbidden.
533
+ *
534
+ * WARNING: this does not clear elements if length is reduced, of initialize elements if length is increased.
535
+ */
536
+ function unsafeSetLength(bytes[] storage array, uint256 len) internal {
537
+ assembly ("memory-safe") {
538
+ sstore(array.slot, len)
539
+ }
540
+ }
541
+
542
+ /**
543
+ * @dev Helper to set the length of a dynamic array. Directly writing to `.length` is forbidden.
544
+ *
545
+ * WARNING: this does not clear elements if length is reduced, of initialize elements if length is increased.
546
+ */
547
+ function unsafeSetLength(string[] storage array, uint256 len) internal {
548
+ assembly ("memory-safe") {
549
+ sstore(array.slot, len)
550
+ }
551
+ }
552
+ }
@@ -0,0 +1,19 @@
1
+ // SPDX-License-Identifier: MIT
2
+ // QRL Contracts (last updated v0.1.0) (utils/Comparators.hyp)
3
+
4
+ pragma hyperion >=0.0;
5
+
6
+ /**
7
+ * @dev Provides a set of functions to compare values.
8
+ *
9
+ * _Available since v5.1._
10
+ */
11
+ library Comparators {
12
+ function lt(uint256 a, uint256 b) internal pure returns (bool) {
13
+ return a < b;
14
+ }
15
+
16
+ function gt(uint256 a, uint256 b) internal pure returns (bool) {
17
+ return a > b;
18
+ }
19
+ }
@@ -0,0 +1,28 @@
1
+ // SPDX-License-Identifier: MIT
2
+ // QRL Contracts (last updated v0.1.0) (utils/Context.hyp)
3
+
4
+ pragma hyperion >=0.0;
5
+
6
+ /**
7
+ * @dev Provides information about the current execution context, including the
8
+ * sender of the transaction and its data. While these are generally available
9
+ * via msg.sender and msg.data, they should not be accessed in such a direct
10
+ * manner, since when dealing with meta-transactions the account sending and
11
+ * paying for execution may not be the actual sender (as far as an application
12
+ * is concerned).
13
+ *
14
+ * This contract is only required for intermediate, library-like contracts.
15
+ */
16
+ abstract contract Context {
17
+ function _msgSender() internal view virtual returns (address) {
18
+ return msg.sender;
19
+ }
20
+
21
+ function _msgData() internal view virtual returns (bytes calldata) {
22
+ return msg.data;
23
+ }
24
+
25
+ function _contextSuffixLength() internal view virtual returns (uint256) {
26
+ return 0;
27
+ }
28
+ }
@@ -0,0 +1,43 @@
1
+ // SPDX-License-Identifier: MIT
2
+ // QRL Contracts v0.1.0 (utils/Counters.hyp)
3
+
4
+ pragma hyperion >=0.0;
5
+
6
+ /**
7
+ * @title Counters
8
+ * @author Matt Condon (@shrugs)
9
+ * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number
10
+ * of elements in a mapping, issuing SQRCTN1 ids, or counting request ids.
11
+ *
12
+ * Include with `using Counters for Counters.Counter;`
13
+ */
14
+ library Counters {
15
+ struct Counter {
16
+ // This variable should never be directly accessed by users of the library: interactions must be restricted to
17
+ // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add
18
+ // this feature: see https://github.com/ethereum/solidity/issues/4637
19
+ uint256 _value; // default: 0
20
+ }
21
+
22
+ function current(Counter storage counter) internal view returns (uint256) {
23
+ return counter._value;
24
+ }
25
+
26
+ function increment(Counter storage counter) internal {
27
+ unchecked {
28
+ counter._value += 1;
29
+ }
30
+ }
31
+
32
+ function decrement(Counter storage counter) internal {
33
+ uint256 value = counter._value;
34
+ require(value > 0, "Counter: decrement overflow");
35
+ unchecked {
36
+ counter._value = value - 1;
37
+ }
38
+ }
39
+
40
+ function reset(Counter storage counter) internal {
41
+ counter._value = 0;
42
+ }
43
+ }
@@ -0,0 +1,57 @@
1
+ // SPDX-License-Identifier: MIT
2
+ // QRL Contracts (last updated v0.1.0) (utils/Panic.hyp)
3
+
4
+ pragma hyperion >=0.0;
5
+
6
+ /**
7
+ * @dev Helper library for emitting standardized panic codes.
8
+ *
9
+ * ```hyperion
10
+ * contract Example {
11
+ * using Panic for uint256;
12
+ *
13
+ * // Use any of the declared internal constants
14
+ * function foo() { Panic.GENERIC.panic(); }
15
+ *
16
+ * // Alternatively
17
+ * function foo() { Panic.panic(Panic.GENERIC); }
18
+ * }
19
+ * ```
20
+ *
21
+ * Follows the list from https://github.com/ethereum/hyperion/blob/v0.8.24/libsolutil/ErrorCodes.h[libsolutil].
22
+ *
23
+ * _Available since v5.1._
24
+ */
25
+ // slither-disable-next-line unused-state
26
+ library Panic {
27
+ /// @dev generic / unspecified error
28
+ uint256 internal constant GENERIC = 0x00;
29
+ /// @dev used by the assert() builtin
30
+ uint256 internal constant ASSERT = 0x01;
31
+ /// @dev arithmetic underflow or overflow
32
+ uint256 internal constant UNDER_OVERFLOW = 0x11;
33
+ /// @dev division or modulo by zero
34
+ uint256 internal constant DIVISION_BY_ZERO = 0x12;
35
+ /// @dev enum conversion error
36
+ uint256 internal constant ENUM_CONVERSION_ERROR = 0x21;
37
+ /// @dev invalid encoding in storage
38
+ uint256 internal constant STORAGE_ENCODING_ERROR = 0x22;
39
+ /// @dev empty array pop
40
+ uint256 internal constant EMPTY_ARRAY_POP = 0x31;
41
+ /// @dev array out of bounds access
42
+ uint256 internal constant ARRAY_OUT_OF_BOUNDS = 0x32;
43
+ /// @dev resource error (too large allocation or too large array)
44
+ uint256 internal constant RESOURCE_ERROR = 0x41;
45
+ /// @dev calling invalid internal function
46
+ uint256 internal constant INVALID_INTERNAL_FUNCTION = 0x51;
47
+
48
+ /// @dev Reverts with a panic code. Recommended to use with
49
+ /// the internal constants with predefined codes.
50
+ function panic(uint256 code) internal pure {
51
+ assembly ("memory-safe") {
52
+ mstore(0x00, 0x4e487b71)
53
+ mstore(0x20, code)
54
+ revert(0x1c, 0x24)
55
+ }
56
+ }
57
+ }