Hi, I am designing a Forwarder with whitelisting function so that this Forwarder only can call by some whitelisted address, so I create a new var _whitelistCaller
and a modifier isWhitelistCaller
. However, when I override the function "execute", the compiler return TypeError: Trying to override non-virtual function. Did you forget to add "virtual"?
So how to solve this issue.
Code to reproduce
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.10;
import '@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol';
import '@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol';
import '@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol';
import '@openzeppelin/contracts-upgradeable/metatx/MinimalForwarderUpgradeable.sol';
import './storages/ForwarderStorage.sol';
contract Forwarder is
Initializable,
UUPSUpgradeable,
OwnableUpgradeable,
MinimalForwarderUpgradeable,
ForwarderStorage
{
// --- EVENT ---
event AddWhitelistCaller(address newWhitelistAddress);
event RemoveWhitelistCaller(address removedWhitelistAddress);
// --- MODIFIER ---
modifier onlyWhitelistCaller() {
require(
isWhitelistCaller(msg.sender),
'Only can call by whitelisted Caller'
);
_;
}
// --- CONSTRUCTOR ---
function initialize() public initializer {
__Ownable_init();
__UUPSUpgradeable_init();
}
// --- EXTERNAL ---
// --- PUBLIC ---
function addWhitelistCaller(address targetAddress) public onlyOwner {
require(targetAddress != address(0), 'targetAddress should not be 0');
require(
!isWhitelistCaller(targetAddress),
'targetAddress is in whitelist'
);
_whitelistCaller[targetAddress] = true;
emit AddWhitelistCaller(targetAddress);
}
function removeWhitelistCaller(address targetAddress) public onlyOwner {
require(targetAddress != address(0), 'targetAddress should not be 0');
require(
isWhitelistCaller(targetAddress),
'targetAddress is not in whitelist'
);
_whitelistCaller[targetAddress] = false;
emit RemoveWhitelistCaller(targetAddress);
}
function execute(ForwardRequest calldata req, bytes calldata signature)
public
payable
override
onlyWhitelistCaller
returns (bool, bytes memory)
{
return super.execute(req, signature);
}
// --- PUBLIC FOR VIEW ---
function isWhitelistCaller(address targetAddress)
public
view
returns (bool)
{
return _whitelistCaller[targetAddress];
}
// --- INTERNAL ---
function _authorizeUpgrade(address newImplementation)
internal
override
onlyOwner
{}
}
pragma solidity ^0.8.9;
abstract contract ForwarderStorage {
mapping(address => bool) internal _whitelistCaller;
}
Environment
- hardhat 2.10.2
- solidity version: 0.8.10