From e87ce615c821d98de24a9935b0e6bab37a13c3cf Mon Sep 17 00:00:00 2001 From: Hadrien Croubois Date: Mon, 25 Jan 2021 10:51:13 +0100 Subject: [PATCH] re-enabling virtual with the addition of internal getters --- contracts/token/ERC1155/ERC1155.sol | 12 +++- contracts/token/ERC20/ERC20.sol | 24 ++++++-- contracts/token/ERC721/ERC721.sol | 85 ++++++++++++++++++++--------- contracts/token/ERC777/ERC777.sol | 24 ++++++-- 4 files changed, 109 insertions(+), 36 deletions(-) diff --git a/contracts/token/ERC1155/ERC1155.sol b/contracts/token/ERC1155/ERC1155.sol index eccc320f4a0..0db5fc2d6e7 100644 --- a/contracts/token/ERC1155/ERC1155.sol +++ b/contracts/token/ERC1155/ERC1155.sol @@ -84,8 +84,7 @@ contract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI { * - `account` cannot be the zero address. */ function balanceOf(address account, uint256 id) public view virtual override returns (uint256) { - require(account != address(0), "ERC1155: balance query for the zero address"); - return _balances[id][account]; + return _getBalanceOf(account, id); } /** @@ -359,6 +358,15 @@ contract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI { virtual { } + /** + * @dev Internal, non-virtual, getter for tokenByIndex. Provide an access to + * the stored values in case the public getter in overloaded. + */ + function _getBalanceOf(address account, uint256 id) internal view returns (uint256) { + require(account != address(0), "ERC1155: balance query for the zero address"); + return _balances[id][account]; + } + function _doSafeTransferAcceptanceCheck( address operator, address from, diff --git a/contracts/token/ERC20/ERC20.sol b/contracts/token/ERC20/ERC20.sol index 1a3dbbba21a..914d2bfe4dd 100644 --- a/contracts/token/ERC20/ERC20.sol +++ b/contracts/token/ERC20/ERC20.sol @@ -93,15 +93,15 @@ contract ERC20 is Context, IERC20 { /** * @dev See {IERC20-totalSupply}. */ - function totalSupply() public view override returns (uint256) { - return _totalSupply; + function totalSupply() public view virtual override returns (uint256) { + return _getTotalSupply(); } /** * @dev See {IERC20-balanceOf}. */ - function balanceOf(address account) public view override returns (uint256) { - return _balances[account]; + function balanceOf(address account) public view virtual override returns (uint256) { + return _getBalanceOf(account); } /** @@ -288,6 +288,22 @@ contract ERC20 is Context, IERC20 { _decimals = decimals_; } + /** + * @dev Internal, non-virtual, getter for tokenByIndex. Provide an access to + * the stored values in case the public getter in overloaded. + */ + function _getTotalSupply() internal view returns (uint256) { + return _totalSupply; + } + + /** + * @dev Internal, non-virtual, getter for tokenByIndex. Provide an access to + * the stored values in case the public getter in overloaded. + */ + function _getBalanceOf(address account) internal view returns (uint256) { + return _balances[account]; + } + /** * @dev Hook that is called before any transfer of tokens. This includes * minting and burning. diff --git a/contracts/token/ERC721/ERC721.sol b/contracts/token/ERC721/ERC721.sol index 49be8f9af66..a8859671d4b 100644 --- a/contracts/token/ERC721/ERC721.sol +++ b/contracts/token/ERC721/ERC721.sol @@ -103,24 +103,15 @@ contract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable /** * @dev See {IERC721-balanceOf}. */ - function balanceOf(address owner) public view override returns (uint256) { - require(owner != address(0), "ERC721: balance query for the zero address"); - - return _holderTokens[owner].length(); + function balanceOf(address owner) public view virtual override returns (uint256) { + return _getBalanceOf(owner); } /** - * @dev See {IERC721-ownerOf}. Overridable + * @dev See {IERC721-ownerOf}. */ function ownerOf(uint256 tokenId) public view virtual override returns (address) { - return _ownerOf(tokenId); - } - - /** - * @dev Owner of the token, as stored internally. Not overridable - */ - function _ownerOf(uint256 tokenId) internal view returns (address) { - return _tokenOwners.get(tokenId, "ERC721: owner query for nonexistent token"); + return _getOwnerOf(tokenId); } /** @@ -169,31 +160,29 @@ contract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable /** * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}. */ - function tokenOfOwnerByIndex(address owner, uint256 index) public view override returns (uint256) { - return _holderTokens[owner].at(index); + function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) { + return _getTokenOfOwnerByIndex(owner, index); } /** * @dev See {IERC721Enumerable-totalSupply}. */ - function totalSupply() public view override returns (uint256) { - // _tokenOwners are indexed by tokenIds, so .length() returns the number of tokenIds - return _tokenOwners.length(); + function totalSupply() public view virtual override returns (uint256) { + return _getTotalSupply(); } /** * @dev See {IERC721Enumerable-tokenByIndex}. */ - function tokenByIndex(uint256 index) public view override returns (uint256) { - (uint256 tokenId, ) = _tokenOwners.at(index); - return tokenId; + function tokenByIndex(uint256 index) public view virtual override returns (uint256) { + return _getTokenByIndex(index); } /** * @dev See {IERC721-approve}. */ function approve(address to, uint256 tokenId) public virtual override { - address owner = _ownerOf(tokenId); + address owner = _getOwnerOf(tokenId); require(to != owner, "ERC721: approval to current owner"); require(_msgSender() == owner || isApprovedForAll(owner, _msgSender()), @@ -298,7 +287,7 @@ contract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable */ function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) { require(_exists(tokenId), "ERC721: operator query for nonexistent token"); - address owner = _ownerOf(tokenId); + address owner = _getOwnerOf(tokenId); return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender)); } @@ -361,7 +350,7 @@ contract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable * Emits a {Transfer} event. */ function _burn(uint256 tokenId) internal virtual { - address owner = _ownerOf(tokenId); // internal owner + address owner = _getOwnerOf(tokenId); // internal owner _beforeTokenTransfer(owner, address(0), tokenId); @@ -392,7 +381,7 @@ contract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable * Emits a {Transfer} event. */ function _transfer(address from, address to, uint256 tokenId) internal virtual { - require(_ownerOf(tokenId) == from, "ERC721: transfer of token that is not own"); // internal owner + require(_getOwnerOf(tokenId) == from, "ERC721: transfer of token that is not own"); // internal owner require(to != address(0), "ERC721: transfer to the zero address"); _beforeTokenTransfer(from, to, tokenId); @@ -429,6 +418,50 @@ contract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable _baseURI = baseURI_; } + + /** + * @dev Internal, non-virtual, getter for balanceOf. Provide an access to + * the stored values in case the public getter in overloaded. + */ + function _getBalanceOf(address owner) internal view returns (uint256) { + require(owner != address(0), "ERC721: balance query for the zero address"); + return _holderTokens[owner].length(); + } + + /** + * @dev Internal, non-virtual, getter for ownerOf. Provide an access to the + * stored values in case the public getter in overloaded. + */ + function _getOwnerOf(uint256 tokenId) internal view returns (address) { + return _tokenOwners.get(tokenId, "ERC721: owner query for nonexistent token"); + } + + /** + * @dev Internal, non-virtual, getter for tokenOfOwnerByIndex. Provide an + * access to the stored values in case the public getter in overloaded. + */ + function _getTokenOfOwnerByIndex(address owner, uint256 index) internal view returns (uint256) { + return _holderTokens[owner].at(index); + } + + /** + * @dev Internal, non-virtual, getter for totalSupply. Provide an access to + * the stored values in case the public getter in overloaded. + */ + function _getTotalSupply() internal view returns (uint256) { + // _tokenOwners are indexed by tokenIds, so .length() returns the number of tokenIds + return _tokenOwners.length(); + } + + /** + * @dev Internal, non-virtual, getter for tokenByIndex. Provide an access to + * the stored values in case the public getter in overloaded. + */ + function _getTokenByIndex(uint256 index) internal view returns (uint256) { + (uint256 tokenId, ) = _tokenOwners.at(index); + return tokenId; + } + /** * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address. * The call is not executed if the target address is not a contract. @@ -458,7 +491,7 @@ contract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable function _approve(address to, uint256 tokenId) private { _tokenApprovals[tokenId] = to; - emit Approval(_ownerOf(tokenId), to, tokenId); // internal owner + emit Approval(_getOwnerOf(tokenId), to, tokenId); // internal owner } /** diff --git a/contracts/token/ERC777/ERC777.sol b/contracts/token/ERC777/ERC777.sol index 259d8e56eb2..ff63140485e 100644 --- a/contracts/token/ERC777/ERC777.sol +++ b/contracts/token/ERC777/ERC777.sol @@ -122,15 +122,15 @@ contract ERC777 is Context, IERC777, IERC20 { /** * @dev See {IERC777-totalSupply}. */ - function totalSupply() public view override(IERC20, IERC777) returns (uint256) { - return _totalSupply; + function totalSupply() public view virtual override(IERC20, IERC777) returns (uint256) { + return _getTotalSupply(); } /** * @dev Returns the amount of tokens owned by an account (`tokenHolder`). */ - function balanceOf(address tokenHolder) public view override(IERC20, IERC777) returns (uint256) { - return _balances[tokenHolder]; + function balanceOf(address tokenHolder) public view virtual override(IERC20, IERC777) returns (uint256) { + return _getBalanceOf(tokenHolder); } /** @@ -434,6 +434,22 @@ contract ERC777 is Context, IERC777, IERC20 { emit Approval(holder, spender, value); } + /** + * @dev Internal, non-virtual, getter for totalSupply. Provide an access to + * the stored values in case the public getter in overloaded. + */ + function _getTotalSupply() internal view returns (uint256) { + return _totalSupply; + } + + /** + * @dev Internal, non-virtual, getter for balanceOf. Provide an access to + * the stored values in case the public getter in overloaded. + */ + function _getBalanceOf(address tokenHolder) internal view returns (uint256) { + return _balances[tokenHolder]; + } + /** * @dev Call from.tokensToSend() if the interface is registered * @param operator address operator requesting the transfer