From 0906c793f2283068419b8fe3d334f2b08baaec27 Mon Sep 17 00:00:00 2001 From: Vectorized Date: Wed, 15 Jun 2022 07:51:56 +0800 Subject: [PATCH] Minor tidy up (#339) * Minor tidy ups * Lint --- contracts/ERC721A.sol | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/contracts/ERC721A.sol b/contracts/ERC721A.sol index 90a821217..5aa39ab95 100644 --- a/contracts/ERC721A.sol +++ b/contracts/ERC721A.sol @@ -19,10 +19,11 @@ interface ERC721A__IERC721Receiver { } /** - * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including - * the Metadata extension. Built to optimize for lower gas during batch mints. + * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, + * including the Metadata extension. Built to optimize for lower gas during batch mints. * - * Assumes serials are sequentially minted starting at _startTokenId() (defaults to 0, e.g. 0, 1, 2, 3..). + * Assumes serials are sequentially minted starting at `_startTokenId()` + * (defaults to 0, e.g. 0, 1, 2, 3..). * * Assumes that an owner cannot have more than 2**64 - 1 (max value of uint64) of supply. * @@ -332,11 +333,13 @@ contract ERC721A is IERC721A { } /** - * @dev Casts the boolean to uint256 without branching. + * @dev Returns the `nextInitialized` flag set if `quantity` equals 1. */ - function _boolToUint256(bool value) private pure returns (uint256 result) { + function _nextInitializedFlag(uint256 quantity) private pure returns (uint256 result) { + // For branchless setting of the `nextInitialized` flag. assembly { - result := value + // `(quantity == 1) << BITPOS_NEXT_INITIALIZED`. + result := shl(BITPOS_NEXT_INITIALIZED, eq(quantity, 1)) } } @@ -499,16 +502,16 @@ contract ERC721A is IERC721A { // - `nextInitialized` to `quantity == 1`. _packedOwnerships[startTokenId] = _packOwnershipData( to, - (_boolToUint256(quantity == 1) << BITPOS_NEXT_INITIALIZED) | _nextExtraData(address(0), to, 0) + _nextInitializedFlag(quantity) | _nextExtraData(address(0), to, 0) ); uint256 tokenId = startTokenId; - uint256 end = quantity + startTokenId; + uint256 end = startTokenId + quantity; do { emit Transfer(address(0), to, tokenId++); } while (tokenId < end); - _currentIndex = startTokenId + quantity; + _currentIndex = end; } _afterTokenTransfers(address(0), to, startTokenId, quantity); } @@ -558,7 +561,7 @@ contract ERC721A is IERC721A { // - `nextInitialized` to `quantity == 1`. _packedOwnerships[startTokenId] = _packOwnershipData( to, - (_boolToUint256(quantity == 1) << BITPOS_NEXT_INITIALIZED) | _nextExtraData(address(0), to, 0) + _nextInitializedFlag(quantity) | _nextExtraData(address(0), to, 0) ); emit ConsecutiveTransfer(startTokenId, startTokenId + quantity - 1, address(0), to); @@ -703,10 +706,11 @@ contract ERC721A is IERC721A { (uint256 approvedAddressSlot, address approvedAddress) = _getApprovedAddress(tokenId); - if (approvalCheck) + if (approvalCheck) { // The nested ifs save around 20+ gas over a compound boolean condition. if (!_isOwnerOrApproved(approvedAddress, from, _msgSenderERC721A())) if (!isApprovedForAll(from, _msgSenderERC721A())) revert TransferCallerNotOwnerNorApproved(); + } _beforeTokenTransfers(from, address(0), tokenId, 1); @@ -830,7 +834,8 @@ contract ERC721A is IERC721A { ) internal view virtual returns (uint24) {} /** - * @dev Hook that is called before a set of serially-ordered token ids are about to be transferred. This includes minting. + * @dev Hook that is called before a set of serially-ordered token ids are about to be transferred. + * This includes minting. * And also called before burning one token. * * startTokenId - the first token id to be transferred @@ -852,8 +857,8 @@ contract ERC721A is IERC721A { ) internal virtual {} /** - * @dev Hook that is called after a set of serially-ordered token ids have been transferred. This includes - * minting. + * @dev Hook that is called after a set of serially-ordered token ids have been transferred. + * This includes minting. * And also called after one token has been burned. * * startTokenId - the first token id to be transferred