Skip to content

Commit 3abbb50

Browse files
Transpile dd1e8988
1 parent 0a71a5e commit 3abbb50

File tree

12 files changed

+316
-311
lines changed

12 files changed

+316
-311
lines changed

scripts/generate/run.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#!/usr/bin/env node
22

3-
const cp = require('child_process');
3+
// const cp = require('child_process');
44
const fs = require('fs');
55
const path = require('path');
66
const format = require('./format-lines');
@@ -23,11 +23,11 @@ function generateFromTemplate(file, template, outputPrefix = '') {
2323
...(version ? [version + ` (${file})`] : []),
2424
`// This file was procedurally generated from ${input}.`,
2525
'',
26-
require(template),
26+
require(template).trimEnd(),
2727
);
2828

2929
fs.writeFileSync(output, content);
30-
cp.execFileSync('prettier', ['--write', output]);
30+
// cp.execFileSync('prettier', ['--write', output]);
3131
}
3232

3333
// Contracts

scripts/generate/templates/Arrays.js

Lines changed: 78 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -15,39 +15,39 @@ import {Math} from "./math/Math.sol";
1515
`;
1616

1717
const sort = type => `\
18-
/**
19-
* @dev Sort an array of ${type} (in memory) following the provided comparator function.
20-
*
21-
* This function does the sorting "in place", meaning that it overrides the input. The object is returned for
22-
* convenience, but that returned value can be discarded safely if the caller has a memory pointer to the array.
23-
*
24-
* 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
25-
* array. Using it in view functions that are executed through \`eth_call\` is safe, but one should be very careful
26-
* when executing this as part of a transaction. If the array being sorted is too large, the sort operation may
27-
* consume more gas than is available in a block, leading to potential DoS.
28-
*/
29-
function sort(
30-
${type}[] memory array,
31-
function(${type}, ${type}) pure returns (bool) comp
32-
) internal pure returns (${type}[] memory) {
33-
${
34-
type === 'bytes32'
35-
? '_quickSort(_begin(array), _end(array), comp);'
36-
: 'sort(_castToBytes32Array(array), _castToBytes32Comp(comp));'
37-
}
38-
return array;
18+
/**
19+
* @dev Sort an array of ${type} (in memory) following the provided comparator function.
20+
*
21+
* This function does the sorting "in place", meaning that it overrides the input. The object is returned for
22+
* convenience, but that returned value can be discarded safely if the caller has a memory pointer to the array.
23+
*
24+
* 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
25+
* array. Using it in view functions that are executed through \`eth_call\` is safe, but one should be very careful
26+
* when executing this as part of a transaction. If the array being sorted is too large, the sort operation may
27+
* consume more gas than is available in a block, leading to potential DoS.
28+
*/
29+
function sort(
30+
${type}[] memory array,
31+
function(${type}, ${type}) pure returns (bool) comp
32+
) internal pure returns (${type}[] memory) {
33+
${
34+
type === 'bytes32'
35+
? '_quickSort(_begin(array), _end(array), comp);'
36+
: 'sort(_castToBytes32Array(array), _castToBytes32Comp(comp));'
3937
}
38+
return array;
39+
}
4040
41-
/**
42-
* @dev Variant of {sort} that sorts an array of ${type} in increasing order.
43-
*/
44-
function sort(${type}[] memory array) internal pure returns (${type}[] memory) {
45-
${type === 'bytes32' ? 'sort(array, _defaultComp);' : 'sort(_castToBytes32Array(array), _defaultComp);'}
46-
return array;
47-
}
41+
/**
42+
* @dev Variant of {sort} that sorts an array of ${type} in increasing order.
43+
*/
44+
function sort(${type}[] memory array) internal pure returns (${type}[] memory) {
45+
${type === 'bytes32' ? 'sort(array, _defaultComp);' : 'sort(_castToBytes32Array(array), _defaultComp);'}
46+
return array;
47+
}
4848
`;
4949

50-
const quickSort = `
50+
const quickSort = `\
5151
/**
5252
* @dev Performs a quick sort of a segment of memory. The segment sorted starts at \`begin\` (inclusive), and stops
5353
* at end (exclusive). Sorting follows the \`comp\` comparator.
@@ -123,34 +123,34 @@ function _swap(uint256 ptr1, uint256 ptr2) private pure {
123123
}
124124
`;
125125

126-
const defaultComparator = `
127-
/// @dev Comparator for sorting arrays in increasing order.
128-
function _defaultComp(bytes32 a, bytes32 b) private pure returns (bool) {
129-
return a < b;
130-
}
126+
const defaultComparator = `\
127+
/// @dev Comparator for sorting arrays in increasing order.
128+
function _defaultComp(bytes32 a, bytes32 b) private pure returns (bool) {
129+
return a < b;
130+
}
131131
`;
132132

133133
const castArray = type => `\
134-
/// @dev Helper: low level cast ${type} memory array to uint256 memory array
135-
function _castToBytes32Array(${type}[] memory input) private pure returns (bytes32[] memory output) {
136-
assembly {
137-
output := input
138-
}
134+
/// @dev Helper: low level cast ${type} memory array to uint256 memory array
135+
function _castToBytes32Array(${type}[] memory input) private pure returns (bytes32[] memory output) {
136+
assembly {
137+
output := input
139138
}
139+
}
140140
`;
141141

142142
const castComparator = type => `\
143-
/// @dev Helper: low level cast ${type} comp function to bytes32 comp function
144-
function _castToBytes32Comp(
145-
function(${type}, ${type}) pure returns (bool) input
146-
) private pure returns (function(bytes32, bytes32) pure returns (bool) output) {
147-
assembly {
148-
output := input
149-
}
143+
/// @dev Helper: low level cast ${type} comp function to bytes32 comp function
144+
function _castToBytes32Comp(
145+
function(${type}, ${type}) pure returns (bool) input
146+
) private pure returns (function(bytes32, bytes32) pure returns (bool) output) {
147+
assembly {
148+
output := input
150149
}
150+
}
151151
`;
152152

153-
const search = `
153+
const search = `\
154154
/**
155155
* @dev Searches a sorted \`array\` and returns the first index that contains
156156
* a value greater or equal to \`element\`. If no such index exists (i.e. all
@@ -319,12 +319,12 @@ function upperBoundMemory(uint256[] memory array, uint256 element) internal pure
319319
}
320320
`;
321321

322-
const unsafeAccessStorage = type => `
322+
const unsafeAccessStorage = type => `\
323323
/**
324-
* @dev Access an array in an "unsafe" way. Skips solidity "index-out-of-range" check.
325-
*
326-
* WARNING: Only use if you are certain \`pos\` is lower than the array length.
327-
*/
324+
* @dev Access an array in an "unsafe" way. Skips solidity "index-out-of-range" check.
325+
*
326+
* WARNING: Only use if you are certain \`pos\` is lower than the array length.
327+
*/
328328
function unsafeAccess(${type}[] storage arr, uint256 pos) internal pure returns (StorageSlot.${capitalize(
329329
type,
330330
)}Slot storage) {
@@ -334,9 +334,10 @@ function unsafeAccess(${type}[] storage arr, uint256 pos) internal pure returns
334334
slot := arr.slot
335335
}
336336
return slot.deriveArray().offset(pos).get${capitalize(type)}Slot();
337-
}`;
337+
}
338+
`;
338339

339-
const unsafeAccessMemory = type => `
340+
const unsafeAccessMemory = type => `\
340341
/**
341342
* @dev Access an array in an "unsafe" way. Skips solidity "index-out-of-range" check.
342343
*
@@ -349,7 +350,7 @@ function unsafeMemoryAccess(${type}[] memory arr, uint256 pos) internal pure ret
349350
}
350351
`;
351352

352-
const unsafeSetLength = type => `
353+
const unsafeSetLength = type => `\
353354
/**
354355
* @dev Helper to set the length of an dynamic array. Directly writing to \`.length\` is forbidden.
355356
*
@@ -360,26 +361,32 @@ function unsafeSetLength(${type}[] storage array, uint256 len) internal {
360361
assembly {
361362
sstore(array.slot, len)
362363
}
363-
}`;
364+
}
365+
`;
364366

365367
// GENERATE
366368
module.exports = format(
367369
header.trimEnd(),
368370
'library Arrays {',
369-
'using SlotDerivation for bytes32;',
370-
'using StorageSlot for bytes32;',
371-
// sorting, comparator, helpers and internal
372-
sort('bytes32'),
373-
TYPES.filter(type => type !== 'bytes32').map(sort),
374-
quickSort,
375-
defaultComparator,
376-
TYPES.filter(type => type !== 'bytes32').map(castArray),
377-
TYPES.filter(type => type !== 'bytes32').map(castComparator),
378-
// lookup
379-
search,
380-
// unsafe (direct) storage and memory access
381-
TYPES.map(unsafeAccessStorage),
382-
TYPES.map(unsafeAccessMemory),
383-
TYPES.map(unsafeSetLength),
371+
format(
372+
[].concat(
373+
'using SlotDerivation for bytes32;',
374+
'using StorageSlot for bytes32;',
375+
'',
376+
// sorting, comparator, helpers and internal
377+
sort('bytes32'),
378+
TYPES.filter(type => type !== 'bytes32').map(sort),
379+
quickSort,
380+
defaultComparator,
381+
TYPES.filter(type => type !== 'bytes32').map(castArray),
382+
TYPES.filter(type => type !== 'bytes32').map(castComparator),
383+
// lookup
384+
search,
385+
// unsafe (direct) storage and memory access
386+
TYPES.map(unsafeAccessStorage),
387+
TYPES.map(unsafeAccessMemory),
388+
TYPES.map(unsafeSetLength),
389+
),
390+
).trimEnd(),
384391
'}',
385392
);

scripts/generate/templates/Checkpoints.js

Lines changed: 18 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@ import {Math} from "../math/Math.sol";
1717
`;
1818

1919
const errors = `\
20-
/**
21-
* @dev A value was attempted to be inserted on a past checkpoint.
22-
*/
23-
error CheckpointUnorderedInsertion();
20+
/**
21+
* @dev A value was attempted to be inserted on a past checkpoint.
22+
*/
23+
error CheckpointUnorderedInsertion();
2424
`;
2525

2626
const template = opts => `\
@@ -37,15 +37,11 @@ struct ${opts.checkpointTypeName} {
3737
* @dev Pushes a (\`key\`, \`value\`) pair into a ${opts.historyTypeName} so that it is stored as the checkpoint.
3838
*
3939
* Returns previous value and new value.
40-
*
40+
*
4141
* IMPORTANT: Never accept \`key\` as a user input, since an arbitrary \`type(${opts.keyTypeName}).max\` key set will disable the
4242
* library.
4343
*/
44-
function push(
45-
${opts.historyTypeName} storage self,
46-
${opts.keyTypeName} key,
47-
${opts.valueTypeName} value
48-
) internal returns (${opts.valueTypeName}, ${opts.valueTypeName}) {
44+
function push(${opts.historyTypeName} storage self, ${opts.keyTypeName} key, ${opts.valueTypeName} value) internal returns (${opts.valueTypeName}, ${opts.valueTypeName}) {
4945
return _insert(self.${opts.checkpointFieldName}, key, value);
5046
}
5147
@@ -108,15 +104,7 @@ function latest(${opts.historyTypeName} storage self) internal view returns (${o
108104
* @dev Returns whether there is a checkpoint in the structure (i.e. it is not empty), and if so the key and value
109105
* in the most recent checkpoint.
110106
*/
111-
function latestCheckpoint(${opts.historyTypeName} storage self)
112-
internal
113-
view
114-
returns (
115-
bool exists,
116-
${opts.keyTypeName} ${opts.keyFieldName},
117-
${opts.valueTypeName} ${opts.valueFieldName}
118-
)
119-
{
107+
function latestCheckpoint(${opts.historyTypeName} storage self) internal view returns (bool exists, ${opts.keyTypeName} ${opts.keyFieldName}, ${opts.valueTypeName} ${opts.valueFieldName}) {
120108
uint256 pos = self.${opts.checkpointFieldName}.length;
121109
if (pos == 0) {
122110
return (false, 0, 0);
@@ -144,11 +132,7 @@ function at(${opts.historyTypeName} storage self, uint32 pos) internal view retu
144132
* @dev Pushes a (\`key\`, \`value\`) pair into an ordered list of checkpoints, either by inserting a new checkpoint,
145133
* or by updating the last one.
146134
*/
147-
function _insert(
148-
${opts.checkpointTypeName}[] storage self,
149-
${opts.keyTypeName} key,
150-
${opts.valueTypeName} value
151-
) private returns (${opts.valueTypeName}, ${opts.valueTypeName}) {
135+
function _insert(${opts.checkpointTypeName}[] storage self, ${opts.keyTypeName} key, ${opts.valueTypeName} value) private returns (${opts.valueTypeName}, ${opts.valueTypeName}) {
152136
uint256 pos = self.length;
153137
154138
if (pos > 0) {
@@ -225,11 +209,10 @@ function _lowerBinaryLookup(
225209
/**
226210
* @dev Access an element of the array without performing bounds check. The position is assumed to be within bounds.
227211
*/
228-
function _unsafeAccess(${opts.checkpointTypeName}[] storage self, uint256 pos)
229-
private
230-
pure
231-
returns (${opts.checkpointTypeName} storage result)
232-
{
212+
function _unsafeAccess(
213+
${opts.checkpointTypeName}[] storage self,
214+
uint256 pos
215+
) private pure returns (${opts.checkpointTypeName} storage result) {
233216
assembly {
234217
mstore(0, self.slot)
235218
result.slot := add(keccak256(0, 0x20), pos)
@@ -242,7 +225,11 @@ function _unsafeAccess(${opts.checkpointTypeName}[] storage self, uint256 pos)
242225
module.exports = format(
243226
header.trimEnd(),
244227
'library Checkpoints {',
245-
errors,
246-
OPTS.flatMap(opts => template(opts)),
228+
format(
229+
[].concat(
230+
errors,
231+
OPTS.map(opts => template(opts)),
232+
),
233+
).trimEnd(),
247234
'}',
248235
);

0 commit comments

Comments
 (0)