Skip to content

Commit ffceb3c

Browse files
authored
Remove hardcoded function resolution (#4299)
1 parent eecd5e1 commit ffceb3c

File tree

5 files changed

+25
-20
lines changed

5 files changed

+25
-20
lines changed

.changeset/red-dots-fold.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'openzeppelin-solidity': major
3+
---
4+
5+
Overrides are now used internally for a number of functions that were previously hardcoded to their default implementation in certain locations: `ERC1155Supply.totalSupply`, `ERC721.ownerOf`, `ERC721.balanceOf` in `ERC721Enumerable`, and `ERC20.totalSupply` in `ERC20FlashMint`.

contracts/token/ERC1155/extensions/ERC1155Supply.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ abstract contract ERC1155Supply is ERC1155 {
3838
* @dev Indicates whether any token exist with a given id, or not.
3939
*/
4040
function exists(uint256 id) public view virtual returns (bool) {
41-
return ERC1155Supply.totalSupply(id) > 0;
41+
return totalSupply(id) > 0;
4242
}
4343

4444
/**

contracts/token/ERC20/extensions/ERC20FlashMint.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ abstract contract ERC20FlashMint is ERC20, IERC3156FlashLender {
2525
* @return The amount of token that can be loaned.
2626
*/
2727
function maxFlashLoan(address token) public view virtual override returns (uint256) {
28-
return token == address(this) ? type(uint256).max - ERC20.totalSupply() : 0;
28+
return token == address(this) ? type(uint256).max - totalSupply() : 0;
2929
}
3030

3131
/**

contracts/token/ERC721/ERC721.sol

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ contract ERC721 is Context, ERC165, IERC721, IERC721Metadata {
108108
* @dev See {IERC721-approve}.
109109
*/
110110
function approve(address to, uint256 tokenId) public virtual override {
111-
address owner = ERC721.ownerOf(tokenId);
111+
address owner = ownerOf(tokenId);
112112
require(to != owner, "ERC721: approval to current owner");
113113

114114
require(
@@ -217,7 +217,7 @@ contract ERC721 is Context, ERC165, IERC721, IERC721Metadata {
217217
* - `tokenId` must exist.
218218
*/
219219
function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {
220-
address owner = ERC721.ownerOf(tokenId);
220+
address owner = ownerOf(tokenId);
221221
return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);
222222
}
223223

@@ -295,21 +295,20 @@ contract ERC721 is Context, ERC165, IERC721, IERC721Metadata {
295295
* Emits a {Transfer} event.
296296
*/
297297
function _burn(uint256 tokenId) internal virtual {
298-
address owner = ERC721.ownerOf(tokenId);
298+
address owner = ownerOf(tokenId);
299299

300300
_beforeTokenTransfer(owner, address(0), tokenId, 1);
301301

302302
// Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook
303-
owner = ERC721.ownerOf(tokenId);
303+
owner = ownerOf(tokenId);
304304

305305
// Clear approvals
306306
delete _tokenApprovals[tokenId];
307307

308-
unchecked {
309-
// Cannot overflow, as that would require more tokens to be burned/transferred
310-
// out than the owner initially received through minting and transferring in.
311-
_balances[owner] -= 1;
312-
}
308+
// Decrease balance with checked arithmetic, because an `ownerOf` override may
309+
// invalidate the assumption that `_balances[from] >= 1`.
310+
_balances[owner] -= 1;
311+
313312
delete _owners[tokenId];
314313

315314
emit Transfer(owner, address(0), tokenId);
@@ -329,26 +328,27 @@ contract ERC721 is Context, ERC165, IERC721, IERC721Metadata {
329328
* Emits a {Transfer} event.
330329
*/
331330
function _transfer(address from, address to, uint256 tokenId) internal virtual {
332-
require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner");
331+
require(ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner");
333332
require(to != address(0), "ERC721: transfer to the zero address");
334333

335334
_beforeTokenTransfer(from, to, tokenId, 1);
336335

337336
// Check that tokenId was not transferred by `_beforeTokenTransfer` hook
338-
require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner");
337+
require(ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner");
339338

340339
// Clear approvals from the previous owner
341340
delete _tokenApprovals[tokenId];
342341

342+
// Decrease balance with checked arithmetic, because an `ownerOf` override may
343+
// invalidate the assumption that `_balances[from] >= 1`.
344+
_balances[from] -= 1;
345+
343346
unchecked {
344-
// `_balances[from]` cannot overflow for the same reason as described in `_burn`:
345-
// `from`'s balance is the number of token held, which is at least one before the current
346-
// transfer.
347347
// `_balances[to]` could overflow in the conditions described in `_mint`. That would require
348348
// all 2**256 token ids to be minted, which in practice is impossible.
349-
_balances[from] -= 1;
350349
_balances[to] += 1;
351350
}
351+
352352
_owners[tokenId] = to;
353353

354354
emit Transfer(from, to, tokenId);
@@ -363,7 +363,7 @@ contract ERC721 is Context, ERC165, IERC721, IERC721Metadata {
363363
*/
364364
function _approve(address to, uint256 tokenId) internal virtual {
365365
_tokenApprovals[tokenId] = to;
366-
emit Approval(ERC721.ownerOf(tokenId), to, tokenId);
366+
emit Approval(ownerOf(tokenId), to, tokenId);
367367
}
368368

369369
/**

contracts/token/ERC721/extensions/ERC721Enumerable.sol

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ abstract contract ERC721Enumerable is ERC721, IERC721Enumerable {
3535
* @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.
3636
*/
3737
function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {
38-
require(index < ERC721.balanceOf(owner), "ERC721Enumerable: owner index out of bounds");
38+
require(index < balanceOf(owner), "ERC721Enumerable: owner index out of bounds");
3939
return _ownedTokens[owner][index];
4040
}
4141

@@ -90,7 +90,7 @@ abstract contract ERC721Enumerable is ERC721, IERC721Enumerable {
9090
* @param tokenId uint256 ID of the token to be added to the tokens list of the given address
9191
*/
9292
function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {
93-
uint256 length = ERC721.balanceOf(to);
93+
uint256 length = balanceOf(to);
9494
_ownedTokens[to][length] = tokenId;
9595
_ownedTokensIndex[tokenId] = length;
9696
}

0 commit comments

Comments
 (0)