TypeError: Function has override specified but does not override anything

After an update from @openzeppelin/contracts in Version 4.6 to 4.8, the solidity compiler complains about the _beforeTokenTransfer-function, that I had to override:

TypeError: Function has override specified but does not override anything.

) internal virtual override (ERC721, ERC721Enumerable, ERC721Pausable) {

And:

TypeError: Invalid contracts specified in override list: "ERC721", "ERC721Enumerable" and "ERC721Pausable".

     ) internal virtual override (ERC721, ERC721Enumerable, ERC721Pausable) {
    |                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Note: This contract: 
  --> @openzeppelin/contracts/token/ERC721/ERC721.sol:19:1:

19 | contract ERC721 is Context, ERC165, IERC721, IERC721Metadata {
   | ^ (Relevant source part starts here and spans across multiple lines).
Note: This contract: 
  --> @openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol:14:1:
   |
14 | abstract contract ERC721Enumerable is ERC721, IERC721Enumerable {
   | ^ (Relevant source part starts here and spans across multiple lines).
Note: This contract: 
  --> @openzeppelin/contracts/token/ERC721/extensions/ERC721Pausable.sol:22:1:
   |
22 | abstract contract ERC721Pausable is ERC721, Pausable {
   | ^ (Relevant source part starts here and spans across multiple lines).

My contract inherits from the following:

contract XYZ is
    ERC721,
    ERC721Enumerable,
    ERC721Burnable,
    ERC721Pausable,
    ERC721URIStorage,
    Ownable,
    AccessControlEnumerable
{
}

Since I have to override _beforeTokenTransfer, I have the following code:

function _beforeTokenTransfer(
    address from,
    address to,
    uint256 amount
) internal virtual override (ERC721, ERC721Enumerable, ERC721Pausable) {
    super._beforeTokenTransfer(from, to, amount);
}

With older OpenZeppelin, it works and compiles. What happend?

From OpenZeppelin Release Notes For v4.8.2:

What does this mean for implementing an custom ERC721? When I remove the _beforeTokenTransfer function it complains

TypeError: Derived contract must override function "_beforeTokenTransfer". Two or more base classes define function with same name and parameter types.

and when I add the _beforeTokenTransfer-Function, it never complies with the overrvide-function.

Is there any Example available?

4.8.2 broke compatibility and changed the signature for _beforeTokenTransfer:

You need to write it like this:

function _beforeTokenTransfer(
    address from,
    address to,
    uint256 firstTokenId,
    uint256 batchSize
) internal virtual override (ERC721, ERC721Enumerable, ERC721Pausable) {
    super._beforeTokenTransfer(from, to, firstTokenId, batchSize);
}
1 Like