Add memory safe assembly annotations (#3384)

Co-authored-by: Nate <nate@Nates-MacBook-Pro.local>
pull/3432/head
Nate Lapinski 3 years ago committed by GitHub
parent c019e7c5bb
commit 65b45726b3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      contracts/metatx/ERC2771Context.sol
  2. 1
      contracts/metatx/MinimalForwarder.sol
  3. 3
      contracts/proxy/Clones.sol
  4. 1
      contracts/token/ERC721/ERC721.sol
  5. 2
      contracts/utils/Address.sol
  6. 1
      contracts/utils/Base64.sol
  7. 4
      contracts/utils/StorageSlot.sol
  8. 2
      contracts/utils/structs/EnumerableSet.sol

@ -24,6 +24,7 @@ abstract contract ERC2771Context is Context {
function _msgSender() internal view virtual override returns (address sender) { function _msgSender() internal view virtual override returns (address sender) {
if (isTrustedForwarder(msg.sender)) { if (isTrustedForwarder(msg.sender)) {
// The assembly code is more direct than the Solidity version using `abi.decode`. // The assembly code is more direct than the Solidity version using `abi.decode`.
/// @solidity memory-safe-assembly
assembly { assembly {
sender := shr(96, calldataload(sub(calldatasize(), 20))) sender := shr(96, calldataload(sub(calldatasize(), 20)))
} }

@ -57,6 +57,7 @@ contract MinimalForwarder is EIP712 {
// We explicitly trigger invalid opcode to consume all gas and bubble-up the effects, since // 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.0 // neither revert or assert consume all gas since Solidity 0.8.0
// https://docs.soliditylang.org/en/v0.8.0/control-structures.html#panic-via-assert-and-error-via-require // https://docs.soliditylang.org/en/v0.8.0/control-structures.html#panic-via-assert-and-error-via-require
/// @solidity memory-safe-assembly
assembly { assembly {
invalid() invalid()
} }

@ -23,6 +23,7 @@ library Clones {
* This function uses the create opcode, which should never revert. * This function uses the create opcode, which should never revert.
*/ */
function clone(address implementation) internal returns (address instance) { function clone(address implementation) internal returns (address instance) {
/// @solidity memory-safe-assembly
assembly { assembly {
let ptr := mload(0x40) let ptr := mload(0x40)
mstore(ptr, 0x602d8060093d393df3363d3d373d3d3d363d7300000000000000000000000000) mstore(ptr, 0x602d8060093d393df3363d3d373d3d3d363d7300000000000000000000000000)
@ -41,6 +42,7 @@ library Clones {
* the clones cannot be deployed twice at the same address. * the clones cannot be deployed twice at the same address.
*/ */
function cloneDeterministic(address implementation, bytes32 salt) internal returns (address instance) { function cloneDeterministic(address implementation, bytes32 salt) internal returns (address instance) {
/// @solidity memory-safe-assembly
assembly { assembly {
let ptr := mload(0x40) let ptr := mload(0x40)
mstore(ptr, 0x602d8060093d393df3363d3d373d3d3d363d7300000000000000000000000000) mstore(ptr, 0x602d8060093d393df3363d3d373d3d3d363d7300000000000000000000000000)
@ -59,6 +61,7 @@ library Clones {
bytes32 salt, bytes32 salt,
address deployer address deployer
) internal pure returns (address predicted) { ) internal pure returns (address predicted) {
/// @solidity memory-safe-assembly
assembly { assembly {
let ptr := mload(0x40) let ptr := mload(0x40)
mstore(ptr, 0x602d8060093d393df3363d3d373d3d3d363d7300000000000000000000000000) mstore(ptr, 0x602d8060093d393df3363d3d373d3d3d363d7300000000000000000000000000)

@ -398,6 +398,7 @@ contract ERC721 is Context, ERC165, IERC721, IERC721Metadata {
if (reason.length == 0) { if (reason.length == 0) {
revert("ERC721: transfer to non ERC721Receiver implementer"); revert("ERC721: transfer to non ERC721Receiver implementer");
} else { } else {
/// @solidity memory-safe-assembly
assembly { assembly {
revert(add(32, reason), mload(reason)) revert(add(32, reason), mload(reason))
} }

@ -209,7 +209,7 @@ library Address {
// Look for revert reason and bubble it up if present // Look for revert reason and bubble it up if present
if (returndata.length > 0) { if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly // The easiest way to bubble the revert reason is using memory via assembly
/// @solidity memory-safe-assembly
assembly { assembly {
let returndata_size := mload(returndata) let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size) revert(add(32, returndata), returndata_size)

@ -35,6 +35,7 @@ library Base64 {
// - `4 *` -> 4 characters for each chunk // - `4 *` -> 4 characters for each chunk
string memory result = new string(4 * ((data.length + 2) / 3)); string memory result = new string(4 * ((data.length + 2) / 3));
/// @solidity memory-safe-assembly
assembly { assembly {
// Prepare the lookup table (skip the first "length" byte) // Prepare the lookup table (skip the first "length" byte)
let tablePtr := add(table, 1) let tablePtr := add(table, 1)

@ -50,6 +50,7 @@ library StorageSlot {
* @dev Returns an `AddressSlot` with member `value` located at `slot`. * @dev Returns an `AddressSlot` with member `value` located at `slot`.
*/ */
function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) { function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {
/// @solidity memory-safe-assembly
assembly { assembly {
r.slot := slot r.slot := slot
} }
@ -59,6 +60,7 @@ library StorageSlot {
* @dev Returns an `BooleanSlot` with member `value` located at `slot`. * @dev Returns an `BooleanSlot` with member `value` located at `slot`.
*/ */
function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) { function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {
/// @solidity memory-safe-assembly
assembly { assembly {
r.slot := slot r.slot := slot
} }
@ -68,6 +70,7 @@ library StorageSlot {
* @dev Returns an `Bytes32Slot` with member `value` located at `slot`. * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.
*/ */
function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) { function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {
/// @solidity memory-safe-assembly
assembly { assembly {
r.slot := slot r.slot := slot
} }
@ -77,6 +80,7 @@ library StorageSlot {
* @dev Returns an `Uint256Slot` with member `value` located at `slot`. * @dev Returns an `Uint256Slot` with member `value` located at `slot`.
*/ */
function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) { function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {
/// @solidity memory-safe-assembly
assembly { assembly {
r.slot := slot r.slot := slot
} }

@ -283,6 +283,7 @@ library EnumerableSet {
bytes32[] memory store = _values(set._inner); bytes32[] memory store = _values(set._inner);
address[] memory result; address[] memory result;
/// @solidity memory-safe-assembly
assembly { assembly {
result := store result := store
} }
@ -356,6 +357,7 @@ library EnumerableSet {
bytes32[] memory store = _values(set._inner); bytes32[] memory store = _values(set._inner);
uint256[] memory result; uint256[] memory result;
/// @solidity memory-safe-assembly
assembly { assembly {
result := store result := store
} }

Loading…
Cancel
Save