@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.
- package/interfaces/ISQRCTN1.hyp +6 -0
- package/interfaces/IZRC165.hyp +6 -0
- package/interfaces/IZRC4906.hyp +20 -0
- package/interfaces/draft-IZRC6093.hyp +161 -0
- package/package.json +26 -0
- package/token/SQRCTB1/ISQRCTB1.hyp +123 -0
- package/token/SQRCTB1/ISQRCTB1Receiver.hyp +59 -0
- package/token/SQRCTB1/SQRCTB1.hyp +389 -0
- package/token/SQRCTB1/extensions/ISQRCTB1MetadataURI.hyp +20 -0
- package/token/SQRCTB1/utils/SQRCTB1Utils.hyp +88 -0
- package/token/SQRCTF1/ISQRCTF1.hyp +79 -0
- package/token/SQRCTF1/SQRCTF1.hyp +305 -0
- package/token/SQRCTF1/extensions/ISQRCTF1Metadata.hyp +26 -0
- package/token/SQRCTN1/ISQRCTN1.hyp +135 -0
- package/token/SQRCTN1/ISQRCTN1Receiver.hyp +28 -0
- package/token/SQRCTN1/SQRCTN1.hyp +430 -0
- package/token/SQRCTN1/extensions/ISQRCTN1Metadata.hyp +27 -0
- package/token/SQRCTN1/extensions/SQRCTN1URIStorage.hyp +58 -0
- package/token/SQRCTN1/utils/SQRCTN1Utils.hyp +50 -0
- package/utils/Arrays.hyp +552 -0
- package/utils/Comparators.hyp +19 -0
- package/utils/Context.hyp +28 -0
- package/utils/Counters.hyp +43 -0
- package/utils/Panic.hyp +57 -0
- package/utils/SlotDerivation.hyp +155 -0
- package/utils/StorageSlot.hyp +143 -0
- package/utils/Strings.hyp +490 -0
- package/utils/introspection/IZRC165.hyp +25 -0
- package/utils/introspection/ZRC165.hyp +25 -0
- package/utils/math/Math.hyp +749 -0
- package/utils/math/SafeCast.hyp +1162 -0
- package/utils/math/SignedMath.hyp +68 -0
package/utils/Arrays.hyp
ADDED
|
@@ -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
|
+
}
|
package/utils/Panic.hyp
ADDED
|
@@ -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
|
+
}
|