Skip to content

Commit

Permalink
Changed _startTokenId to _currentIndex
Browse files Browse the repository at this point in the history
  • Loading branch information
Vectorized committed Feb 13, 2022
1 parent 02dff65 commit ca96c35
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 19 deletions.
30 changes: 15 additions & 15 deletions contracts/ERC721A.sol
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,10 @@ contract ERC721A is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable
}

// Compiler will pack the following
// _nextTokenId and _burnCounter into a single 256bit word.
// _currentIndex and _burnCounter into a single 256bit word.

// The id of the next token to be minted.
uint128 internal _nextTokenId;
uint128 internal _currentIndex;

// The number of tokens burned.
uint128 internal _burnCounter;
Expand All @@ -95,7 +95,7 @@ contract ERC721A is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable
constructor(string memory name_, string memory symbol_) {
_name = name_;
_symbol = symbol_;
_nextTokenId = uint128(_startTokenId());
_currentIndex = uint128(_startTokenId());
}

/**
Expand All @@ -116,9 +116,9 @@ contract ERC721A is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable
*/
function totalSupply() public view override returns (uint256) {
// Counter underflow is impossible as _burnCounter cannot be incremented
// more than _nextTokenId - _startTokenId() times
// more than _currentIndex - _startTokenId() times
unchecked {
return _nextTokenId - _burnCounter - _startTokenId();
return _currentIndex - _burnCounter - _startTokenId();
}
}

Expand All @@ -128,7 +128,7 @@ contract ERC721A is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable
* It may also degrade with extremely large collection sizes (e.g >> 10000), test for your use case.
*/
function tokenByIndex(uint256 index) public view override returns (uint256) {
uint256 end = _nextTokenId;
uint256 end = _currentIndex;
uint256 tokenIdsIdx;

// Counter overflow is impossible as the loop breaks when
Expand All @@ -154,7 +154,7 @@ contract ERC721A is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable
*/
function tokenOfOwnerByIndex(address owner, uint256 index) public view override returns (uint256) {
if (index >= balanceOf(owner)) revert OwnerIndexOutOfBounds();
uint256 end = _nextTokenId;
uint256 end = _currentIndex;
uint256 tokenIdsIdx;
address currOwnershipAddr;

Expand Down Expand Up @@ -219,7 +219,7 @@ contract ERC721A is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable
uint256 curr = tokenId;

unchecked {
if (_startTokenId() <= curr && curr < _nextTokenId) {
if (_startTokenId() <= curr && curr < _currentIndex) {
TokenOwnership memory ownership = _ownerships[curr];
if (!ownership.burned) {
if (ownership.addr != address(0)) {
Expand Down Expand Up @@ -367,7 +367,7 @@ contract ERC721A is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable
* Tokens start existing when they are minted (`_mint`),
*/
function _exists(uint256 tokenId) internal view returns (bool) {
return _startTokenId() <= tokenId && tokenId < _nextTokenId &&
return _startTokenId() <= tokenId && tokenId < _currentIndex &&
!_ownerships[tokenId].burned;
}

Expand Down Expand Up @@ -409,15 +409,15 @@ contract ERC721A is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable
bytes memory _data,
bool safe
) internal {
uint256 startTokenId = _nextTokenId;
uint256 startTokenId = _currentIndex;
if (to == address(0)) revert MintToZeroAddress();
if (quantity == 0) revert MintZeroQuantity();

_beforeTokenTransfers(address(0), to, startTokenId, quantity);

// Overflows are incredibly unrealistic.
// balance or numberMinted overflow if current value of either + quantity > 3.4e38 (2**128) - 1
// updatedIndex overflows if _nextTokenId + quantity > 3.4e38 (2**128) - 1
// updatedIndex overflows if _currentIndex + quantity > 3.4e38 (2**128) - 1
unchecked {
_addressData[to].balance += uint64(quantity);
_addressData[to].numberMinted += uint64(quantity);
Expand All @@ -435,7 +435,7 @@ contract ERC721A is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable
updatedIndex++;
}

_nextTokenId = uint128(updatedIndex);
_currentIndex = uint128(updatedIndex);
}
_afterTokenTransfers(address(0), to, startTokenId, quantity);
}
Expand Down Expand Up @@ -486,7 +486,7 @@ contract ERC721A is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable
if (_ownerships[nextTokenId].addr == address(0)) {
// This will suffice for checking _exists(nextTokenId),
// as a burned slot cannot contain the zero address.
if (nextTokenId < _nextTokenId) {
if (nextTokenId < _currentIndex) {
_ownerships[nextTokenId].addr = prevOwnership.addr;
_ownerships[nextTokenId].startTimestamp = prevOwnership.startTimestamp;
}
Expand Down Expand Up @@ -533,7 +533,7 @@ contract ERC721A is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable
if (_ownerships[nextTokenId].addr == address(0)) {
// This will suffice for checking _exists(nextTokenId),
// as a burned slot cannot contain the zero address.
if (nextTokenId < _nextTokenId) {
if (nextTokenId < _currentIndex) {
_ownerships[nextTokenId].addr = prevOwnership.addr;
_ownerships[nextTokenId].startTimestamp = prevOwnership.startTimestamp;
}
Expand All @@ -543,7 +543,7 @@ contract ERC721A is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable
emit Transfer(prevOwnership.addr, address(0), tokenId);
_afterTokenTransfers(prevOwnership.addr, address(0), tokenId, 1);

// Overflow not possible, as _burnCounter cannot be exceed _nextTokenId times.
// Overflow not possible, as _burnCounter cannot be exceed _currentIndex times.
unchecked {
_burnCounter++;
}
Expand Down
8 changes: 4 additions & 4 deletions contracts/extensions/ERC721AOwnersExplicit.sol
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,21 @@ abstract contract ERC721AOwnersExplicit is ERC721A {
*/
function _setOwnersExplicit(uint256 quantity) internal {
if (quantity == 0) revert QuantityMustBeNonZero();
if (_nextTokenId == _startTokenId()) revert NoTokensMintedYet();
if (_currentIndex == _startTokenId()) revert NoTokensMintedYet();
uint256 _nextOwnerToExplicitlySet = nextOwnerToExplicitlySet;
if (_nextOwnerToExplicitlySet == 0) {
_nextOwnerToExplicitlySet = _startTokenId();
}
if (_nextOwnerToExplicitlySet >= _nextTokenId) revert AllOwnershipsHaveBeenSet();
if (_nextOwnerToExplicitlySet >= _currentIndex) revert AllOwnershipsHaveBeenSet();

// Index underflow is impossible.
// Counter or index overflow is incredibly unrealistic.
unchecked {
uint256 endIndex = _nextOwnerToExplicitlySet + quantity - 1;

// Set the end index to be the last token index
if (endIndex + 1 > _nextTokenId) {
endIndex = _nextTokenId - 1;
if (endIndex + 1 > _currentIndex) {
endIndex = _currentIndex - 1;
}

for (uint256 i = _nextOwnerToExplicitlySet; i <= endIndex; i++) {
Expand Down

0 comments on commit ca96c35

Please sign in to comment.