Optimize array allocation in ERC1155 (#4196)

Co-authored-by: Francisco <fg@frang.io>
This commit is contained in:
Renan Souza
2023-06-02 11:37:59 -03:00
committed by GitHub
parent 30256fa838
commit 5cef83d2c7
2 changed files with 23 additions and 10 deletions

View File

@ -0,0 +1,5 @@
---
'openzeppelin-solidity': patch
---
`ERC1155`: Optimize array allocation.

View File

@ -206,8 +206,7 @@ contract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {
function _safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes memory data) internal { function _safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes memory data) internal {
require(to != address(0), "ERC1155: transfer to the zero address"); require(to != address(0), "ERC1155: transfer to the zero address");
require(from != address(0), "ERC1155: transfer from the zero address"); require(from != address(0), "ERC1155: transfer from the zero address");
uint256[] memory ids = _asSingletonArray(id); (uint256[] memory ids, uint256[] memory amounts) = _asSingletonArrays(id, amount);
uint256[] memory amounts = _asSingletonArray(amount);
_update(from, to, ids, amounts, data); _update(from, to, ids, amounts, data);
} }
@ -269,8 +268,7 @@ contract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {
*/ */
function _mint(address to, uint256 id, uint256 amount, bytes memory data) internal { function _mint(address to, uint256 id, uint256 amount, bytes memory data) internal {
require(to != address(0), "ERC1155: mint to the zero address"); require(to != address(0), "ERC1155: mint to the zero address");
uint256[] memory ids = _asSingletonArray(id); (uint256[] memory ids, uint256[] memory amounts) = _asSingletonArrays(id, amount);
uint256[] memory amounts = _asSingletonArray(amount);
_update(address(0), to, ids, amounts, data); _update(address(0), to, ids, amounts, data);
} }
@ -302,8 +300,7 @@ contract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {
*/ */
function _burn(address from, uint256 id, uint256 amount) internal { function _burn(address from, uint256 id, uint256 amount) internal {
require(from != address(0), "ERC1155: burn from the zero address"); require(from != address(0), "ERC1155: burn from the zero address");
uint256[] memory ids = _asSingletonArray(id); (uint256[] memory ids, uint256[] memory amounts) = _asSingletonArrays(id, amount);
uint256[] memory amounts = _asSingletonArray(amount);
_update(from, address(0), ids, amounts, ""); _update(from, address(0), ids, amounts, "");
} }
@ -376,10 +373,21 @@ contract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {
} }
} }
function _asSingletonArray(uint256 element) private pure returns (uint256[] memory) { function _asSingletonArrays(
uint256[] memory array = new uint256[](1); uint256 element1,
array[0] = element; uint256 element2
) private pure returns (uint256[] memory array1, uint256[] memory array2) {
/// @solidity memory-safe-assembly
assembly {
array1 := mload(0x40)
mstore(array1, 1)
mstore(add(array1, 0x20), element1)
return array; array2 := add(array1, 0x40)
mstore(array2, 1)
mstore(add(array2, 0x20), element2)
mstore(0x40, add(array2, 0x40))
}
} }
} }