From d8bbd346762c7bf9f594777dfab788d214423ced Mon Sep 17 00:00:00 2001 From: Hadrien Croubois Date: Thu, 29 Aug 2024 23:07:17 +0200 Subject: [PATCH] Update declaration of memory safe assembly blocks (#5172) --- contracts/metatx/ERC2771Forwarder.sol | 6 +- contracts/proxy/Clones.sol | 9 +-- contracts/token/ERC1155/ERC1155.sol | 3 +- .../token/ERC1155/utils/ERC1155Utils.sol | 6 +- contracts/token/ERC20/utils/ERC1363Utils.sol | 6 +- contracts/token/ERC721/utils/ERC721Utils.sol | 3 +- contracts/utils/Address.sol | 3 +- contracts/utils/Arrays.sol | 21 +++---- contracts/utils/Base64.sol | 3 +- contracts/utils/Create2.sol | 6 +- contracts/utils/Panic.sol | 3 +- contracts/utils/ShortStrings.sol | 3 +- contracts/utils/SlotDerivation.sol | 27 +++------ contracts/utils/StorageSlot.sol | 57 +++++++------------ contracts/utils/Strings.sol | 6 +- contracts/utils/cryptography/ECDSA.sol | 3 +- contracts/utils/cryptography/Hashes.sol | 3 +- .../utils/cryptography/MessageHashUtils.sol | 6 +- contracts/utils/math/Math.sol | 6 +- contracts/utils/math/SafeCast.sol | 3 +- contracts/utils/structs/EnumerableMap.sol | 24 +++----- contracts/utils/structs/EnumerableSet.sol | 9 +-- contracts/utils/structs/Heap.sol | 6 +- scripts/generate/templates/Arrays.js | 9 +-- scripts/generate/templates/EnumerableMap.js | 3 +- scripts/generate/templates/EnumerableSet.js | 3 +- scripts/generate/templates/Heap.js | 3 +- scripts/generate/templates/SafeCast.js | 3 +- scripts/generate/templates/SlotDerivation.js | 12 ++-- scripts/generate/templates/StorageSlot.js | 12 ++-- test/proxy/Clones.t.sol | 3 +- test/utils/Create2.t.sol | 3 +- 32 files changed, 91 insertions(+), 182 deletions(-) diff --git a/contracts/metatx/ERC2771Forwarder.sol b/contracts/metatx/ERC2771Forwarder.sol index 03c3bee70c6..b5e943d920c 100644 --- a/contracts/metatx/ERC2771Forwarder.sol +++ b/contracts/metatx/ERC2771Forwarder.sol @@ -309,8 +309,7 @@ contract ERC2771Forwarder is EIP712, Nonces { bool success; uint256 returnSize; uint256 returnValue; - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { // Perform the staticcall and save the result in the scratch space. // | Location | Content | Content (Hex) | // |-----------|----------|--------------------------------------------------------------------| @@ -362,8 +361,7 @@ contract ERC2771Forwarder is EIP712, Nonces { // We explicitly trigger invalid opcode to consume all gas and bubble-up the effects, since // neither revert or assert consume all gas since Solidity 0.8.20 // https://docs.soliditylang.org/en/v0.8.20/control-structures.html#panic-via-assert-and-error-via-require - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { invalid() } } diff --git a/contracts/proxy/Clones.sol b/contracts/proxy/Clones.sol index d243d67f34b..097b43b43b3 100644 --- a/contracts/proxy/Clones.sol +++ b/contracts/proxy/Clones.sol @@ -37,8 +37,7 @@ library Clones { if (address(this).balance < value) { revert Errors.InsufficientBalance(address(this).balance, value); } - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { // Cleans the upper 96 bits of the `implementation` word, then packs the first 3 bytes // of the `implementation` address with the bytecode before the address. mstore(0x00, or(shr(0xe8, shl(0x60, implementation)), 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000)) @@ -77,8 +76,7 @@ library Clones { if (address(this).balance < value) { revert Errors.InsufficientBalance(address(this).balance, value); } - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { // Cleans the upper 96 bits of the `implementation` word, then packs the first 3 bytes // of the `implementation` address with the bytecode before the address. mstore(0x00, or(shr(0xe8, shl(0x60, implementation)), 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000)) @@ -99,8 +97,7 @@ library Clones { bytes32 salt, address deployer ) internal pure returns (address predicted) { - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { let ptr := mload(0x40) mstore(add(ptr, 0x38), deployer) mstore(add(ptr, 0x24), 0x5af43d82803e903d91602b57fd5bf3ff) diff --git a/contracts/token/ERC1155/ERC1155.sol b/contracts/token/ERC1155/ERC1155.sol index 5e05e4791dd..b0e7e547ab2 100644 --- a/contracts/token/ERC1155/ERC1155.sol +++ b/contracts/token/ERC1155/ERC1155.sol @@ -381,8 +381,7 @@ abstract contract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI, IER uint256 element1, uint256 element2 ) private pure returns (uint256[] memory array1, uint256[] memory array2) { - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { // Load the free memory pointer array1 := mload(0x40) // Set array length to 1 diff --git a/contracts/token/ERC1155/utils/ERC1155Utils.sol b/contracts/token/ERC1155/utils/ERC1155Utils.sol index 0ff2bf146a4..a07539bd018 100644 --- a/contracts/token/ERC1155/utils/ERC1155Utils.sol +++ b/contracts/token/ERC1155/utils/ERC1155Utils.sol @@ -38,8 +38,7 @@ library ERC1155Utils { // non-IERC1155Receiver implementer revert IERC1155Errors.ERC1155InvalidReceiver(to); } else { - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { revert(add(32, reason), mload(reason)) } } @@ -76,8 +75,7 @@ library ERC1155Utils { // non-IERC1155Receiver implementer revert IERC1155Errors.ERC1155InvalidReceiver(to); } else { - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { revert(add(32, reason), mload(reason)) } } diff --git a/contracts/token/ERC20/utils/ERC1363Utils.sol b/contracts/token/ERC20/utils/ERC1363Utils.sol index e6af49de5d3..f5c931361f7 100644 --- a/contracts/token/ERC20/utils/ERC1363Utils.sol +++ b/contracts/token/ERC20/utils/ERC1363Utils.sol @@ -51,8 +51,7 @@ library ERC1363Utils { if (reason.length == 0) { revert ERC1363InvalidReceiver(to); } else { - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { revert(add(32, reason), mload(reason)) } } @@ -86,8 +85,7 @@ library ERC1363Utils { if (reason.length == 0) { revert ERC1363InvalidSpender(spender); } else { - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { revert(add(32, reason), mload(reason)) } } diff --git a/contracts/token/ERC721/utils/ERC721Utils.sol b/contracts/token/ERC721/utils/ERC721Utils.sol index 43dd107b296..712ac16a70a 100644 --- a/contracts/token/ERC721/utils/ERC721Utils.sol +++ b/contracts/token/ERC721/utils/ERC721Utils.sol @@ -37,8 +37,7 @@ library ERC721Utils { // non-IERC721Receiver implementer revert IERC721Errors.ERC721InvalidReceiver(to); } else { - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { revert(add(32, reason), mload(reason)) } } diff --git a/contracts/utils/Address.sol b/contracts/utils/Address.sol index 53a3c442049..40f01a93dca 100644 --- a/contracts/utils/Address.sol +++ b/contracts/utils/Address.sol @@ -139,8 +139,7 @@ library Address { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } diff --git a/contracts/utils/Arrays.sol b/contracts/utils/Arrays.sol index fe54bafee7c..14f4ce297ae 100644 --- a/contracts/utils/Arrays.sol +++ b/contracts/utils/Arrays.sol @@ -134,8 +134,7 @@ library Arrays { * @dev Pointer to the memory location of the first element of `array`. */ function _begin(uint256[] memory array) private pure returns (uint256 ptr) { - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { ptr := add(array, 0x20) } } @@ -377,8 +376,7 @@ library Arrays { */ function unsafeAccess(address[] storage arr, uint256 pos) internal pure returns (StorageSlot.AddressSlot storage) { bytes32 slot; - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { slot := arr.slot } return slot.deriveArray().offset(pos).getAddressSlot(); @@ -391,8 +389,7 @@ library Arrays { */ function unsafeAccess(bytes32[] storage arr, uint256 pos) internal pure returns (StorageSlot.Bytes32Slot storage) { bytes32 slot; - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { slot := arr.slot } return slot.deriveArray().offset(pos).getBytes32Slot(); @@ -405,8 +402,7 @@ library Arrays { */ function unsafeAccess(uint256[] storage arr, uint256 pos) internal pure returns (StorageSlot.Uint256Slot storage) { bytes32 slot; - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { slot := arr.slot } return slot.deriveArray().offset(pos).getUint256Slot(); @@ -451,8 +447,7 @@ library Arrays { * WARNING: this does not clear elements if length is reduced, of initialize elements if length is increased. */ function unsafeSetLength(address[] storage array, uint256 len) internal { - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { sstore(array.slot, len) } } @@ -463,8 +458,7 @@ library Arrays { * WARNING: this does not clear elements if length is reduced, of initialize elements if length is increased. */ function unsafeSetLength(bytes32[] storage array, uint256 len) internal { - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { sstore(array.slot, len) } } @@ -475,8 +469,7 @@ library Arrays { * WARNING: this does not clear elements if length is reduced, of initialize elements if length is increased. */ function unsafeSetLength(uint256[] storage array, uint256 len) internal { - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { sstore(array.slot, len) } } diff --git a/contracts/utils/Base64.sol b/contracts/utils/Base64.sol index 630dc66be9c..be0b7d687fb 100644 --- a/contracts/utils/Base64.sol +++ b/contracts/utils/Base64.sol @@ -55,8 +55,7 @@ library Base64 { string memory result = new string(resultLength); - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { // Prepare the lookup table (skip the first "length" byte) let tablePtr := add(table, 1) diff --git a/contracts/utils/Create2.sol b/contracts/utils/Create2.sol index a88ce25f643..121eb0c742a 100644 --- a/contracts/utils/Create2.sol +++ b/contracts/utils/Create2.sol @@ -41,8 +41,7 @@ library Create2 { if (bytecode.length == 0) { revert Create2EmptyBytecode(); } - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { addr := create2(amount, add(bytecode, 0x20), mload(bytecode), salt) // if no address was created, and returndata is not empty, bubble revert if and(iszero(addr), not(iszero(returndatasize()))) { @@ -69,8 +68,7 @@ library Create2 { * `deployer`. If `deployer` is this contract's address, returns the same value as {computeAddress}. */ function computeAddress(bytes32 salt, bytes32 bytecodeHash, address deployer) internal pure returns (address addr) { - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { let ptr := mload(0x40) // Get free memory pointer // | | ↓ ptr ... ↓ ptr + 0x0B (start) ... ↓ ptr + 0x20 ... ↓ ptr + 0x40 ... | diff --git a/contracts/utils/Panic.sol b/contracts/utils/Panic.sol index b6443035cf5..8769bd9a786 100644 --- a/contracts/utils/Panic.sol +++ b/contracts/utils/Panic.sol @@ -45,8 +45,7 @@ library Panic { /// @dev Reverts with a panic code. Recommended to use with /// the internal constants with predefined codes. function panic(uint256 code) internal pure { - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { mstore(0x00, 0x4e487b71) mstore(0x20, code) revert(0x1c, 0x24) diff --git a/contracts/utils/ShortStrings.sol b/contracts/utils/ShortStrings.sol index fdfe774d635..78fc5cd963d 100644 --- a/contracts/utils/ShortStrings.sol +++ b/contracts/utils/ShortStrings.sol @@ -64,8 +64,7 @@ library ShortStrings { uint256 len = byteLength(sstr); // using `new string(len)` would work locally but is not memory safe. string memory str = new string(32); - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { mstore(str, len) mstore(add(str, 0x20), sstr) } diff --git a/contracts/utils/SlotDerivation.sol b/contracts/utils/SlotDerivation.sol index c75941b5886..62c28a55fa6 100644 --- a/contracts/utils/SlotDerivation.sol +++ b/contracts/utils/SlotDerivation.sol @@ -40,8 +40,7 @@ library SlotDerivation { * @dev Derive an ERC-7201 slot from a string (namespace). */ function erc7201Slot(string memory namespace) internal pure returns (bytes32 slot) { - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { mstore(0x00, sub(keccak256(add(namespace, 0x20), mload(namespace)), 1)) slot := and(keccak256(0x00, 0x20), not(0xff)) } @@ -60,8 +59,7 @@ library SlotDerivation { * @dev Derive the location of the first element in an array from the slot where the length is stored. */ function deriveArray(bytes32 slot) internal pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { mstore(0x00, slot) result := keccak256(0x00, 0x20) } @@ -71,8 +69,7 @@ library SlotDerivation { * @dev Derive the location of a mapping element from the key. */ function deriveMapping(bytes32 slot, address key) internal pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { mstore(0x00, key) mstore(0x20, slot) result := keccak256(0x00, 0x40) @@ -83,8 +80,7 @@ library SlotDerivation { * @dev Derive the location of a mapping element from the key. */ function deriveMapping(bytes32 slot, bool key) internal pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { mstore(0x00, key) mstore(0x20, slot) result := keccak256(0x00, 0x40) @@ -95,8 +91,7 @@ library SlotDerivation { * @dev Derive the location of a mapping element from the key. */ function deriveMapping(bytes32 slot, bytes32 key) internal pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { mstore(0x00, key) mstore(0x20, slot) result := keccak256(0x00, 0x40) @@ -107,8 +102,7 @@ library SlotDerivation { * @dev Derive the location of a mapping element from the key. */ function deriveMapping(bytes32 slot, uint256 key) internal pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { mstore(0x00, key) mstore(0x20, slot) result := keccak256(0x00, 0x40) @@ -119,8 +113,7 @@ library SlotDerivation { * @dev Derive the location of a mapping element from the key. */ function deriveMapping(bytes32 slot, int256 key) internal pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { mstore(0x00, key) mstore(0x20, slot) result := keccak256(0x00, 0x40) @@ -131,8 +124,7 @@ library SlotDerivation { * @dev Derive the location of a mapping element from the key. */ function deriveMapping(bytes32 slot, string memory key) internal pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { let length := mload(key) let begin := add(key, 0x20) let end := add(begin, length) @@ -147,8 +139,7 @@ library SlotDerivation { * @dev Derive the location of a mapping element from the key. */ function deriveMapping(bytes32 slot, bytes memory key) internal pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { let length := mload(key) let begin := add(key, 0x20) let end := add(begin, length) diff --git a/contracts/utils/StorageSlot.sol b/contracts/utils/StorageSlot.sol index e560717d2fa..2e4f736d8d1 100644 --- a/contracts/utils/StorageSlot.sol +++ b/contracts/utils/StorageSlot.sol @@ -82,8 +82,7 @@ library StorageSlot { * @dev Returns an `AddressSlot` with member `value` located at `slot`. */ function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) { - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { r.slot := slot } } @@ -92,8 +91,7 @@ library StorageSlot { * @dev Returns a `BooleanSlot` with member `value` located at `slot`. */ function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) { - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { r.slot := slot } } @@ -102,8 +100,7 @@ library StorageSlot { * @dev Returns a `Bytes32Slot` with member `value` located at `slot`. */ function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) { - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { r.slot := slot } } @@ -112,8 +109,7 @@ library StorageSlot { * @dev Returns a `Uint256Slot` with member `value` located at `slot`. */ function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) { - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { r.slot := slot } } @@ -122,8 +118,7 @@ library StorageSlot { * @dev Returns a `Int256Slot` with member `value` located at `slot`. */ function getInt256Slot(bytes32 slot) internal pure returns (Int256Slot storage r) { - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { r.slot := slot } } @@ -132,8 +127,7 @@ library StorageSlot { * @dev Returns a `StringSlot` with member `value` located at `slot`. */ function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) { - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { r.slot := slot } } @@ -142,8 +136,7 @@ library StorageSlot { * @dev Returns an `StringSlot` representation of the string storage pointer `store`. */ function getStringSlot(string storage store) internal pure returns (StringSlot storage r) { - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { r.slot := store.slot } } @@ -152,8 +145,7 @@ library StorageSlot { * @dev Returns a `BytesSlot` with member `value` located at `slot`. */ function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) { - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { r.slot := slot } } @@ -162,8 +154,7 @@ library StorageSlot { * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`. */ function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) { - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { r.slot := store.slot } } @@ -232,8 +223,7 @@ library StorageSlot { * @dev Load the value held at location `slot` in transient storage. */ function tload(AddressSlotType slot) internal view returns (address value) { - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { value := tload(slot) } } @@ -242,8 +232,7 @@ library StorageSlot { * @dev Store `value` at location `slot` in transient storage. */ function tstore(AddressSlotType slot, address value) internal { - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { tstore(slot, value) } } @@ -252,8 +241,7 @@ library StorageSlot { * @dev Load the value held at location `slot` in transient storage. */ function tload(BooleanSlotType slot) internal view returns (bool value) { - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { value := tload(slot) } } @@ -262,8 +250,7 @@ library StorageSlot { * @dev Store `value` at location `slot` in transient storage. */ function tstore(BooleanSlotType slot, bool value) internal { - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { tstore(slot, value) } } @@ -272,8 +259,7 @@ library StorageSlot { * @dev Load the value held at location `slot` in transient storage. */ function tload(Bytes32SlotType slot) internal view returns (bytes32 value) { - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { value := tload(slot) } } @@ -282,8 +268,7 @@ library StorageSlot { * @dev Store `value` at location `slot` in transient storage. */ function tstore(Bytes32SlotType slot, bytes32 value) internal { - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { tstore(slot, value) } } @@ -292,8 +277,7 @@ library StorageSlot { * @dev Load the value held at location `slot` in transient storage. */ function tload(Uint256SlotType slot) internal view returns (uint256 value) { - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { value := tload(slot) } } @@ -302,8 +286,7 @@ library StorageSlot { * @dev Store `value` at location `slot` in transient storage. */ function tstore(Uint256SlotType slot, uint256 value) internal { - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { tstore(slot, value) } } @@ -312,8 +295,7 @@ library StorageSlot { * @dev Load the value held at location `slot` in transient storage. */ function tload(Int256SlotType slot) internal view returns (int256 value) { - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { value := tload(slot) } } @@ -322,8 +304,7 @@ library StorageSlot { * @dev Store `value` at location `slot` in transient storage. */ function tstore(Int256SlotType slot, int256 value) internal { - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { tstore(slot, value) } } diff --git a/contracts/utils/Strings.sol b/contracts/utils/Strings.sol index 164d8acd07d..5448060b70e 100644 --- a/contracts/utils/Strings.sol +++ b/contracts/utils/Strings.sol @@ -26,14 +26,12 @@ library Strings { uint256 length = Math.log10(value) + 1; string memory buffer = new string(length); uint256 ptr; - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { ptr := add(buffer, add(32, length)) } while (true) { ptr--; - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { mstore8(ptr, byte(mod(value, 10), HEX_DIGITS)) } value /= 10; diff --git a/contracts/utils/cryptography/ECDSA.sol b/contracts/utils/cryptography/ECDSA.sol index 864c8ee8766..3736171bf9f 100644 --- a/contracts/utils/cryptography/ECDSA.sol +++ b/contracts/utils/cryptography/ECDSA.sol @@ -60,8 +60,7 @@ library ECDSA { uint8 v; // ecrecover takes the signature parameters, and the only way to get them // currently is to use assembly. - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { r := mload(add(signature, 0x20)) s := mload(add(signature, 0x40)) v := byte(0, mload(add(signature, 0x60))) diff --git a/contracts/utils/cryptography/Hashes.sol b/contracts/utils/cryptography/Hashes.sol index 434a8494251..c78bc80fd79 100644 --- a/contracts/utils/cryptography/Hashes.sol +++ b/contracts/utils/cryptography/Hashes.sol @@ -19,8 +19,7 @@ library Hashes { * @dev Implementation of keccak256(abi.encode(a, b)) that doesn't allocate or expand memory. */ function _efficientKeccak256(bytes32 a, bytes32 b) private pure returns (bytes32 value) { - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { mstore(0x00, a) mstore(0x20, b) value := keccak256(0x00, 0x40) diff --git a/contracts/utils/cryptography/MessageHashUtils.sol b/contracts/utils/cryptography/MessageHashUtils.sol index 45c2421ad96..35746ce72ce 100644 --- a/contracts/utils/cryptography/MessageHashUtils.sol +++ b/contracts/utils/cryptography/MessageHashUtils.sol @@ -28,8 +28,7 @@ library MessageHashUtils { * See {ECDSA-recover}. */ function toEthSignedMessageHash(bytes32 messageHash) internal pure returns (bytes32 digest) { - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { mstore(0x00, "\x19Ethereum Signed Message:\n32") // 32 is the bytes-length of messageHash mstore(0x1c, messageHash) // 0x1c (28) is the length of the prefix digest := keccak256(0x00, 0x3c) // 0x3c is the length of the prefix (0x1c) + messageHash (0x20) @@ -74,8 +73,7 @@ library MessageHashUtils { * See {ECDSA-recover}. */ function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 digest) { - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { let ptr := mload(0x40) mstore(ptr, hex"19_01") mstore(add(ptr, 0x02), domainSeparator) diff --git a/contracts/utils/math/Math.sol b/contracts/utils/math/Math.sol index 96af9ad247f..9e277f3f50d 100644 --- a/contracts/utils/math/Math.sol +++ b/contracts/utils/math/Math.sol @@ -336,8 +336,7 @@ library Math { */ function tryModExp(uint256 b, uint256 e, uint256 m) internal view returns (bool success, uint256 result) { if (m == 0) return (false, 0); - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { let ptr := mload(0x40) // | Offset | Content | Content (Hex) | // |-----------|------------|--------------------------------------------------------------------| @@ -387,8 +386,7 @@ library Math { // Encode call args in result and move the free memory pointer result = abi.encodePacked(b.length, e.length, mLen, b, e, m); - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { let dataPtr := add(result, 0x20) // Write result on top of args to avoid allocating extra memory. success := staticcall(gas(), 0x05, dataPtr, mload(result), dataPtr, mLen) diff --git a/contracts/utils/math/SafeCast.sol b/contracts/utils/math/SafeCast.sol index d8de2e17c49..36832006ebf 100644 --- a/contracts/utils/math/SafeCast.sol +++ b/contracts/utils/math/SafeCast.sol @@ -1155,8 +1155,7 @@ library SafeCast { * @dev Cast a boolean (false or true) to a uint256 (0 or 1) with no jump. */ function toUint(bool b) internal pure returns (uint256 u) { - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { u := iszero(iszero(b)) } } diff --git a/contracts/utils/structs/EnumerableMap.sol b/contracts/utils/structs/EnumerableMap.sol index 814916b69ae..e61182e1fbd 100644 --- a/contracts/utils/structs/EnumerableMap.sol +++ b/contracts/utils/structs/EnumerableMap.sol @@ -245,8 +245,7 @@ library EnumerableMap { bytes32[] memory store = keys(map._inner); uint256[] memory result; - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { result := store } @@ -339,8 +338,7 @@ library EnumerableMap { bytes32[] memory store = keys(map._inner); uint256[] memory result; - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { result := store } @@ -433,8 +431,7 @@ library EnumerableMap { bytes32[] memory store = keys(map._inner); uint256[] memory result; - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { result := store } @@ -527,8 +524,7 @@ library EnumerableMap { bytes32[] memory store = keys(map._inner); address[] memory result; - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { result := store } @@ -621,8 +617,7 @@ library EnumerableMap { bytes32[] memory store = keys(map._inner); address[] memory result; - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { result := store } @@ -715,8 +710,7 @@ library EnumerableMap { bytes32[] memory store = keys(map._inner); address[] memory result; - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { result := store } @@ -809,8 +803,7 @@ library EnumerableMap { bytes32[] memory store = keys(map._inner); bytes32[] memory result; - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { result := store } @@ -903,8 +896,7 @@ library EnumerableMap { bytes32[] memory store = keys(map._inner); bytes32[] memory result; - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { result := store } diff --git a/contracts/utils/structs/EnumerableSet.sol b/contracts/utils/structs/EnumerableSet.sol index 4c7fc5e1d76..90fcfa9d77b 100644 --- a/contracts/utils/structs/EnumerableSet.sol +++ b/contracts/utils/structs/EnumerableSet.sol @@ -220,8 +220,7 @@ library EnumerableSet { bytes32[] memory store = _values(set._inner); bytes32[] memory result; - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { result := store } @@ -294,8 +293,7 @@ library EnumerableSet { bytes32[] memory store = _values(set._inner); address[] memory result; - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { result := store } @@ -368,8 +366,7 @@ library EnumerableSet { bytes32[] memory store = _values(set._inner); uint256[] memory result; - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { result := store } diff --git a/contracts/utils/structs/Heap.sol b/contracts/utils/structs/Heap.sol index 64c3ecd2b1f..269c4723f34 100644 --- a/contracts/utils/structs/Heap.sol +++ b/contracts/utils/structs/Heap.sol @@ -212,8 +212,7 @@ library Heap { */ function clear(Uint256Heap storage self) internal { Uint256HeapNode[] storage data = self.data; - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { sstore(data.slot, 0) } } @@ -479,8 +478,7 @@ library Heap { */ function clear(Uint208Heap storage self) internal { Uint208HeapNode[] storage data = self.data; - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { sstore(data.slot, 0) } } diff --git a/scripts/generate/templates/Arrays.js b/scripts/generate/templates/Arrays.js index 9823e4e5d7b..3a1e62237ee 100644 --- a/scripts/generate/templates/Arrays.js +++ b/scripts/generate/templates/Arrays.js @@ -86,8 +86,7 @@ function _quickSort(uint256 begin, uint256 end, function(uint256, uint256) pure * @dev Pointer to the memory location of the first element of \`array\`. */ function _begin(uint256[] memory array) private pure returns (uint256 ptr) { - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { ptr := add(array, 0x20) } } @@ -323,8 +322,7 @@ function unsafeAccess(${type}[] storage arr, uint256 pos) internal pure returns type, )}Slot storage) { bytes32 slot; - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { slot := arr.slot } return slot.deriveArray().offset(pos).get${capitalize(type)}Slot(); @@ -351,8 +349,7 @@ const unsafeSetLength = type => `\ * WARNING: this does not clear elements if length is reduced, of initialize elements if length is increased. */ function unsafeSetLength(${type}[] storage array, uint256 len) internal { - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { sstore(array.slot, len) } } diff --git a/scripts/generate/templates/EnumerableMap.js b/scripts/generate/templates/EnumerableMap.js index bcc8edd76e5..656d8463dec 100644 --- a/scripts/generate/templates/EnumerableMap.js +++ b/scripts/generate/templates/EnumerableMap.js @@ -250,8 +250,7 @@ function keys(${name} storage map) internal view returns (${keyType}[] memory) { bytes32[] memory store = keys(map._inner); ${keyType}[] memory result; - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { result := store } diff --git a/scripts/generate/templates/EnumerableSet.js b/scripts/generate/templates/EnumerableSet.js index d1878775aaf..351466b1313 100644 --- a/scripts/generate/templates/EnumerableSet.js +++ b/scripts/generate/templates/EnumerableSet.js @@ -227,8 +227,7 @@ function values(${name} storage set) internal view returns (${type}[] memory) { bytes32[] memory store = _values(set._inner); ${type}[] memory result; - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { result := store } diff --git a/scripts/generate/templates/Heap.js b/scripts/generate/templates/Heap.js index 5ef042a98b2..558ed1b9115 100644 --- a/scripts/generate/templates/Heap.js +++ b/scripts/generate/templates/Heap.js @@ -214,8 +214,7 @@ function length(${struct} storage self) internal view returns (${indexType}) { */ function clear(${struct} storage self) internal { ${struct}Node[] storage data = self.data; - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { sstore(data.slot, 0) } } diff --git a/scripts/generate/templates/SafeCast.js b/scripts/generate/templates/SafeCast.js index 8a9ce9fc765..a3b32e3f00a 100644 --- a/scripts/generate/templates/SafeCast.js +++ b/scripts/generate/templates/SafeCast.js @@ -121,8 +121,7 @@ const boolToUint = `\ * @dev Cast a boolean (false or true) to a uint256 (0 or 1) with no jump. */ function toUint(bool b) internal pure returns (uint256 u) { - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { u := iszero(iszero(b)) } } diff --git a/scripts/generate/templates/SlotDerivation.js b/scripts/generate/templates/SlotDerivation.js index d8ab35d6f75..5311fb3c8d1 100644 --- a/scripts/generate/templates/SlotDerivation.js +++ b/scripts/generate/templates/SlotDerivation.js @@ -43,8 +43,7 @@ const namespace = `\ * @dev Derive an ERC-7201 slot from a string (namespace). */ function erc7201Slot(string memory namespace) internal pure returns (bytes32 slot) { - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { mstore(0x00, sub(keccak256(add(namespace, 0x20), mload(namespace)), 1)) slot := and(keccak256(0x00, 0x20), not(0xff)) } @@ -65,8 +64,7 @@ function offset(bytes32 slot, uint256 pos) internal pure returns (bytes32 result * @dev Derive the location of the first element in an array from the slot where the length is stored. */ function deriveArray(bytes32 slot) internal pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { mstore(0x00, slot) result := keccak256(0x00, 0x20) } @@ -78,8 +76,7 @@ const mapping = ({ type }) => `\ * @dev Derive the location of a mapping element from the key. */ function deriveMapping(bytes32 slot, ${type} key) internal pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { mstore(0x00, key) mstore(0x20, slot) result := keccak256(0x00, 0x40) @@ -92,8 +89,7 @@ const mapping2 = ({ type }) => `\ * @dev Derive the location of a mapping element from the key. */ function deriveMapping(bytes32 slot, ${type} memory key) internal pure returns (bytes32 result) { - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { let length := mload(key) let begin := add(key, 0x20) let end := add(begin, length) diff --git a/scripts/generate/templates/StorageSlot.js b/scripts/generate/templates/StorageSlot.js index 829e639c694..7a00f5e225c 100644 --- a/scripts/generate/templates/StorageSlot.js +++ b/scripts/generate/templates/StorageSlot.js @@ -64,8 +64,7 @@ const get = ({ name }) => `\ } \`${name}Slot\` with member \`value\` located at \`slot\`. */ function get${name}Slot(bytes32 slot) internal pure returns (${name}Slot storage r) { - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { r.slot := slot } } @@ -76,8 +75,7 @@ const getStorage = ({ type, name }) => `\ * @dev Returns an \`${name}Slot\` representation of the ${type} storage pointer \`store\`. */ function get${name}Slot(${type} storage store) internal pure returns (${name}Slot storage r) { - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { r.slot := store.slot } } @@ -102,8 +100,7 @@ const transient = ({ type, name }) => `\ * @dev Load the value held at location \`slot\` in transient storage. */ function tload(${name}SlotType slot) internal view returns (${type} value) { - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { value := tload(slot) } } @@ -112,8 +109,7 @@ function tload(${name}SlotType slot) internal view returns (${type} value) { * @dev Store \`value\` at location \`slot\` in transient storage. */ function tstore(${name}SlotType slot, ${type} value) internal { - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { tstore(slot, value) } } diff --git a/test/proxy/Clones.t.sol b/test/proxy/Clones.t.sol index 4301e103c26..31b072b98de 100644 --- a/test/proxy/Clones.t.sol +++ b/test/proxy/Clones.t.sol @@ -13,8 +13,7 @@ contract ClonesTest is Test { function testSymbolicPredictDeterministicAddressSpillage(address implementation, bytes32 salt) public { address predicted = Clones.predictDeterministicAddress(implementation, salt); bytes32 spillage; - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { spillage := and(predicted, 0xffffffffffffffffffffffff0000000000000000000000000000000000000000) } assertEq(spillage, bytes32(0)); diff --git a/test/utils/Create2.t.sol b/test/utils/Create2.t.sol index e8e2269f68a..6cc037a3b3b 100644 --- a/test/utils/Create2.t.sol +++ b/test/utils/Create2.t.sol @@ -9,8 +9,7 @@ contract Create2Test is Test { function testSymbolicComputeAddressSpillage(bytes32 salt, bytes32 bytecodeHash, address deployer) public { address predicted = Create2.computeAddress(salt, bytecodeHash, deployer); bytes32 spillage; - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { spillage := and(predicted, 0xffffffffffffffffffffffff0000000000000000000000000000000000000000) } assertEq(spillage, bytes32(0));