Skip to content

Commit 7a7e398

Browse files
Transpile fd99f6922
1 parent 5b5ea1c commit 7a7e398

File tree

14 files changed

+374
-27
lines changed

14 files changed

+374
-27
lines changed

.changeset/swift-planets-juggle.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'openzeppelin-solidity': minor
3+
---
4+
5+
`Arrays`: Add `slice` and `splice` functions for value types (`uint256[]`, `bytes32[]`, `address[]`).

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
- `ERC6909` and its extensions (`ERC6909ContentURI`, `ERC6909Metadata` and `ERC6909TokenSupply`) are no longer marked as draft since [EIP-6909](https://eips.ethereum.org/EIPS/eip-6909) is now final. Developers must update the import paths. Contracts behavior is not modified. ([#5929](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/5929))
1414
- `SignerERC7702` is renamed as `SignerEIP7702`. Imports and inheritance must be updated to that new name and path. Behavior is unmodified. ([#5932](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/5932))
1515
- `ERC721Holder`, `ERC1155Holder`, `ReentrancyGuard` and `ReentrancyGuardTransient` are flagged as stateless and are no longer transpiled. Developers using their upgradeable variants from `@openzeppelin/contracts-upgradeable` must update their imports to use the equivalent version available in `@openzeppelin/contracts`. ([#5944](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/5944), [#5942](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/5942))
16-
- Update minimum pragma to 0.8.24 in `Votes`, `VotesExtended`, `ERC20Votes`, `Strings`, `ERC1155URIStorage`, `MessageHashUtils`, `ERC721URIStorage`, `ERC721Votes`, `ERC721Wrapper`, `ERC721Burnable`, `ERC721Consecutive`, `ERC721Enumerable`, `ERC721Pausable`, `ERC721Royalty`, `ERC721Wrapper`, `EIP712`, `ERC4626` and `ERC7739`. ([#5726](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/5726))
16+
- Update minimum pragma to 0.8.24 in `AccessControlEnumerable`, `Arrays`, `CircularBuffer`, `EIP712`, `EnumerableMap`, `EnumerableSet`, `ERC1155`, `ERC1155Burnable`, `ERC1155Pausable`, `ERC1155Supply`, `ERC1155URIStorage`, `ERC20Votes`, `ERC4626`,`ERC721Burnable`, `ERC721Consecutive`, `ERC721Enumerable`, `ERC721Pausable`, `ERC721Royalty`, `ERC721URIStorage`, `ERC721Votes`, `ERC721Wrapper`, `ERC7739`, `Heap`, `MerkleTree`, `MessageHashUtils`, `Strings`, `Votes` and `VotesExtended`. ([#5723](https://github.com/OpenZeppelin/openzeppelin-contracts/issues/5723), [#5726](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/5726), [#5965](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/5965))
1717
- `Account`: Add `signature` argument to the internal `_validateUserOp` function for custom signature handling logic. Developers overriding it must now provide the signature from the user operation (i.e. `userOp.signature`) to keep compatibility. ([#5976](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/5976))
1818
- `AccountERC7579`: Installing and uninstalling fallback modules now require the corresponding `initData` and `deInitData` arguments to be at least 4 bytes long (matching the selector to which the fallback module is registered). It now reverts with `ERC7579CannotDecodeFallbackData` instead of treating the missing bytes as `0x00`. ([#5974](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/5974))
1919

contracts/access/extensions/AccessControlEnumerableUpgradeable.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// SPDX-License-Identifier: MIT
22
// OpenZeppelin Contracts (last updated v5.4.0) (access/extensions/AccessControlEnumerable.sol)
33

4-
pragma solidity ^0.8.20;
4+
pragma solidity ^0.8.24;
55

66
import {IAccessControlEnumerable} from "@openzeppelin/contracts/access/extensions/IAccessControlEnumerable.sol";
77
import {AccessControlUpgradeable} from "../AccessControlUpgradeable.sol";

contracts/token/ERC1155/ERC1155Upgradeable.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// SPDX-License-Identifier: MIT
22
// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC1155/ERC1155.sol)
33

4-
pragma solidity ^0.8.20;
4+
pragma solidity ^0.8.24;
55

66
import {IERC1155} from "@openzeppelin/contracts/token/ERC1155/IERC1155.sol";
77
import {IERC1155MetadataURI} from "@openzeppelin/contracts/token/ERC1155/extensions/IERC1155MetadataURI.sol";

contracts/token/ERC1155/extensions/ERC1155BurnableUpgradeable.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// SPDX-License-Identifier: MIT
22
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC1155/extensions/ERC1155Burnable.sol)
33

4-
pragma solidity ^0.8.20;
4+
pragma solidity ^0.8.24;
55

66
import {ERC1155Upgradeable} from "../ERC1155Upgradeable.sol";
77
import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";

contracts/token/ERC1155/extensions/ERC1155PausableUpgradeable.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// SPDX-License-Identifier: MIT
22
// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC1155/extensions/ERC1155Pausable.sol)
33

4-
pragma solidity ^0.8.20;
4+
pragma solidity ^0.8.24;
55

66
import {ERC1155Upgradeable} from "../ERC1155Upgradeable.sol";
77
import {PausableUpgradeable} from "../../../utils/PausableUpgradeable.sol";

contracts/token/ERC1155/extensions/ERC1155SupplyUpgradeable.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// SPDX-License-Identifier: MIT
22
// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC1155/extensions/ERC1155Supply.sol)
33

4-
pragma solidity ^0.8.20;
4+
pragma solidity ^0.8.24;
55

66
import {ERC1155Upgradeable} from "../ERC1155Upgradeable.sol";
77
import {Arrays} from "@openzeppelin/contracts/utils/Arrays.sol";

scripts/generate/templates/Arrays.js

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ const { capitalize } = require('../../helpers');
33
const { TYPES } = require('./Arrays.opts');
44

55
const header = `\
6-
pragma solidity ^0.8.20;
6+
pragma solidity ^0.8.24;
77
88
import {Comparators} from "./Comparators.sol";
99
import {SlotDerivation} from "./SlotDerivation.sol";
@@ -359,6 +359,71 @@ function unsafeSetLength(${type.name}[] storage array, uint256 len) internal {
359359
}
360360
`;
361361

362+
const slice = type => `\
363+
/**
364+
* @dev Copies the content of \`array\`, from \`start\` (included) to the end of \`array\` into a new ${type.name} array in
365+
* memory.
366+
*
367+
* NOTE: replicates the behavior of https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice[Javascript's \`Array.slice\`]
368+
*/
369+
function slice(${type.name}[] memory array, uint256 start) internal pure returns (${type.name}[] memory) {
370+
return slice(array, start, array.length);
371+
}
372+
373+
/**
374+
* @dev Copies the content of \`array\`, from \`start\` (included) to \`end\` (excluded) into a new ${type.name} array in
375+
* memory. The \`end\` argument is truncated to the length of the \`array\`.
376+
*
377+
* NOTE: replicates the behavior of https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice[Javascript's \`Array.slice\`]
378+
*/
379+
function slice(${type.name}[] memory array, uint256 start, uint256 end) internal pure returns (${type.name}[] memory) {
380+
// sanitize
381+
end = Math.min(end, array.length);
382+
start = Math.min(start, end);
383+
384+
// allocate and copy
385+
${type.name}[] memory result = new ${type.name}[](end - start);
386+
assembly ("memory-safe") {
387+
mcopy(add(result, 0x20), add(add(array, 0x20), mul(start, 0x20)), mul(sub(end, start), 0x20))
388+
}
389+
390+
return result;
391+
}
392+
`;
393+
394+
const splice = type => `\
395+
/**
396+
* @dev Moves the content of \`array\`, from \`start\` (included) to the end of \`array\` to the start of that array.
397+
*
398+
* NOTE: This function modifies the provided array in place. If you need to preserve the original array, use {slice} instead.
399+
* NOTE: replicates the behavior of https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice[Javascript's \`Array.splice\`]
400+
*/
401+
function splice(${type.name}[] memory array, uint256 start) internal pure returns (${type.name}[] memory) {
402+
return splice(array, start, array.length);
403+
}
404+
405+
/**
406+
* @dev Moves the content of \`array\`, from \`start\` (included) to \`end\` (excluded) to the start of that array. The
407+
* \`end\` argument is truncated to the length of the \`array\`.
408+
*
409+
* NOTE: This function modifies the provided array in place. If you need to preserve the original array, use {slice} instead.
410+
* NOTE: replicates the behavior of https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice[Javascript's \`Array.splice\`]
411+
*/
412+
function splice(${type.name}[] memory array, uint256 start, uint256 end) internal pure returns (${type.name}[] memory) {
413+
// sanitize
414+
end = Math.min(end, array.length);
415+
start = Math.min(start, end);
416+
417+
// move and resize
418+
assembly ("memory-safe") {
419+
mcopy(add(array, 0x20), add(add(array, 0x20), mul(start, 0x20)), mul(sub(end, start), 0x20))
420+
mstore(array, sub(end, start))
421+
}
422+
423+
return array;
424+
}
425+
`;
426+
362427
// GENERATE
363428
module.exports = format(
364429
header.trimEnd(),
@@ -376,6 +441,9 @@ module.exports = format(
376441
TYPES.filter(type => type.isValueType && type.name !== 'uint256').map(castComparator),
377442
// lookup
378443
search,
444+
// slice and splice for value types only
445+
TYPES.filter(type => type.isValueType).map(slice),
446+
TYPES.filter(type => type.isValueType).map(splice),
379447
// unsafe (direct) storage and memory access
380448
TYPES.map(unsafeAccessStorage),
381449
TYPES.map(unsafeAccessMemory),

scripts/generate/templates/EnumerableMap.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ const { fromBytes32, toBytes32 } = require('./conversion');
33
const { MAP_TYPES } = require('./Enumerable.opts');
44

55
const header = `\
6-
pragma solidity ^0.8.20;
6+
pragma solidity ^0.8.24;
77
88
import {EnumerableSet} from "./EnumerableSet.sol";
99

0 commit comments

Comments
 (0)