|
@@ -108,7 +108,7 @@ contract ERC721 is Context, ERC165, IERC721, IERC721Metadata {
|
|
|
* @dev See {IERC721-approve}.
|
|
|
*/
|
|
|
function approve(address to, uint256 tokenId) public virtual override {
|
|
|
- address owner = ERC721.ownerOf(tokenId);
|
|
|
+ address owner = ownerOf(tokenId);
|
|
|
require(to != owner, "ERC721: approval to current owner");
|
|
|
|
|
|
require(
|
|
@@ -217,7 +217,7 @@ contract ERC721 is Context, ERC165, IERC721, IERC721Metadata {
|
|
|
* - `tokenId` must exist.
|
|
|
*/
|
|
|
function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {
|
|
|
- address owner = ERC721.ownerOf(tokenId);
|
|
|
+ address owner = ownerOf(tokenId);
|
|
|
return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);
|
|
|
}
|
|
|
|
|
@@ -295,21 +295,20 @@ contract ERC721 is Context, ERC165, IERC721, IERC721Metadata {
|
|
|
* Emits a {Transfer} event.
|
|
|
*/
|
|
|
function _burn(uint256 tokenId) internal virtual {
|
|
|
- address owner = ERC721.ownerOf(tokenId);
|
|
|
+ address owner = ownerOf(tokenId);
|
|
|
|
|
|
_beforeTokenTransfer(owner, address(0), tokenId, 1);
|
|
|
|
|
|
// Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook
|
|
|
- owner = ERC721.ownerOf(tokenId);
|
|
|
+ owner = ownerOf(tokenId);
|
|
|
|
|
|
// Clear approvals
|
|
|
delete _tokenApprovals[tokenId];
|
|
|
|
|
|
- unchecked {
|
|
|
- // Cannot overflow, as that would require more tokens to be burned/transferred
|
|
|
- // out than the owner initially received through minting and transferring in.
|
|
|
- _balances[owner] -= 1;
|
|
|
- }
|
|
|
+ // Decrease balance with checked arithmetic, because an `ownerOf` override may
|
|
|
+ // invalidate the assumption that `_balances[from] >= 1`.
|
|
|
+ _balances[owner] -= 1;
|
|
|
+
|
|
|
delete _owners[tokenId];
|
|
|
|
|
|
emit Transfer(owner, address(0), tokenId);
|
|
@@ -329,26 +328,27 @@ contract ERC721 is Context, ERC165, IERC721, IERC721Metadata {
|
|
|
* Emits a {Transfer} event.
|
|
|
*/
|
|
|
function _transfer(address from, address to, uint256 tokenId) internal virtual {
|
|
|
- require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner");
|
|
|
+ require(ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner");
|
|
|
require(to != address(0), "ERC721: transfer to the zero address");
|
|
|
|
|
|
_beforeTokenTransfer(from, to, tokenId, 1);
|
|
|
|
|
|
// Check that tokenId was not transferred by `_beforeTokenTransfer` hook
|
|
|
- require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner");
|
|
|
+ require(ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner");
|
|
|
|
|
|
// Clear approvals from the previous owner
|
|
|
delete _tokenApprovals[tokenId];
|
|
|
|
|
|
+ // Decrease balance with checked arithmetic, because an `ownerOf` override may
|
|
|
+ // invalidate the assumption that `_balances[from] >= 1`.
|
|
|
+ _balances[from] -= 1;
|
|
|
+
|
|
|
unchecked {
|
|
|
- // `_balances[from]` cannot overflow for the same reason as described in `_burn`:
|
|
|
- // `from`'s balance is the number of token held, which is at least one before the current
|
|
|
- // transfer.
|
|
|
// `_balances[to]` could overflow in the conditions described in `_mint`. That would require
|
|
|
// all 2**256 token ids to be minted, which in practice is impossible.
|
|
|
- _balances[from] -= 1;
|
|
|
_balances[to] += 1;
|
|
|
}
|
|
|
+
|
|
|
_owners[tokenId] = to;
|
|
|
|
|
|
emit Transfer(from, to, tokenId);
|
|
@@ -363,7 +363,7 @@ contract ERC721 is Context, ERC165, IERC721, IERC721Metadata {
|
|
|
*/
|
|
|
function _approve(address to, uint256 tokenId) internal virtual {
|
|
|
_tokenApprovals[tokenId] = to;
|
|
|
- emit Approval(ERC721.ownerOf(tokenId), to, tokenId);
|
|
|
+ emit Approval(ownerOf(tokenId), to, tokenId);
|
|
|
}
|
|
|
|
|
|
/**
|