I am trying to extend MulticallUpgradeable
and UUPSUpgradeable
in the same contract; however, the two parts clash, as both define private
_functionDelegateCall
, making overriding to resolve the conflict not an option.
What's the right approach here?
Code to reproduce
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.2;
import "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol";
import "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721BurnableUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/utils/MulticallUpgradeable.sol";
contract ERC721Burnable is Initializable, ERC721Upgradeable, ERC721BurnableUpgradeable, MulticallUpgradeable, OwnableUpgradeable, UUPSUpgradeable {
function initialize() initializer public {
__ERC721_init("ERC721Burnable", "MTK");
__ERC721Burnable_init();
__Multicall_init();
__Ownable_init();
__UUPSUpgradeable_init();
}
function _authorizeUpgrade(address newImplementation)
internal
onlyOwner
override
{}
}
Expected: contract compiles.
Observed:
TypeError: Derived contract must override function "_functionDelegateCall". Two or more base classes define function with same name and parameter types.
--> src/ERC721Burnable.sol:13:1:
|
13 | contract ERC721Burnable is
| ^ (Relevant source part starts here and spans across multiple lines).
Note: Definition in "ERC1967UpgradeUpgradeable":
--> @openzeppelin/contracts-upgradeable/proxy/ERC1967/ERC1967UpgradeUpgradeable.sol:207:5:
|
207 | function _functionDelegateCall(address target, bytes memory data) private returns (bytes memory) {
| ^ (Relevant source part starts here and spans across multiple lines).
Note: Definition in "MulticallUpgradeable":
--> @openzeppelin/contracts-upgradeable/utils/MulticallUpgradeable.sol:37:5:
|
37 | function _functionDelegateCall(address target, bytes memory data) private returns (bytes memory) {
| ^ (Relevant source part starts here and spans across multiple lines).
Error HH600: Compilation failed
or, if an attempt to override _functionDelegateCall
is made,
TypeError: Trying to override non-virtual function. Did you forget to add "virtual"?
--> @openzeppelin/contracts-upgradeable/utils/MulticallUpgradeable.sol:37:5:
|
37 | function _functionDelegateCall(address target, bytes memory data) private returns (bytes memory) {
| ^ (Relevant source part starts here and spans across multiple lines).
Note: Overriding function is here:
--> src/ERC721Burnable.sol:78:5:
|
78 | function _functionDelegateCall(address target, bytes memory data)
| ^ (Relevant source part starts here and spans across multiple lines).
TypeError: Trying to override non-virtual function. Did you forget to add "virtual"?
--> @openzeppelin/contracts-upgradeable/proxy/ERC1967/ERC1967UpgradeUpgradeable.sol:207:5:
|
207 | function _functionDelegateCall(address target, bytes memory data) private returns (bytes memory) {
| ^ (Relevant source part starts here and spans across multiple lines).
Note: Overriding function is here:
--> src/ERC721Burnable.sol:78:5:
|
78 | function _functionDelegateCall(address target, bytes memory data)
| ^ (Relevant source part starts here and spans across multiple lines).
Error HH600: Compilation failed
Environment
-
hardhat
2.6.1 -
solc
0.8.7 -
@openzeppelin/contracts-upgradeable
4.3.1