I'm trying to create an upgradeable ERC20 contract from a Factory but I'm receiving an error, these are my contracts: The token contract
// SPDX-License-Identifier: MIT
pragma solidity 0.8.7;
import "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
import "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import "@openzeppelin/contracts-upgradeable/utils/math/SafeMathUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/utils/cryptography/ECDSAUpgradeable.sol";
contract Token is
Initializable,
ERC20Upgradeable,
ERC20BurnableUpgradeable,
PausableUpgradeable,
OwnableUpgradeable
{
//This function gets called by the TokenFactory contract
function initialize(string memory _name, string memory _symbol)
public
initializer
{
__ERC20_init(_name, _symbol);
__ERC20Burnable_init();
__Pausable_init();
__Ownable_init();
}
}
This is my factory contract:
// SPDX-License-Identifier: MIT
pragma solidity 0.8.7;
import "@openzeppelin/contracts/proxy/beacon/BeaconProxy.sol";
import "./TokenBeacon.sol";
import "./Token.sol";
contract TokenFactory {
mapping(uint32 => address) private tokens;
TokenBeacon immutable beacon;
constructor(address _initialBlueprint) {
beacon = new TokenBeacon(_initialBlueprint);
}
//More information on BeaconProxy: https://docs.openzeppelin.com/contracts/4.x/api/proxy#BeaconProxy
function createToken(string memory _name, string memory _symbol, uint32 _tokenID) public {
BeaconProxy token = new BeaconProxy(
address(beacon),
abi.encodeWithSelector(
Token(address(0)).initialize.selector,
_name,
_symbol
)
);
tokens[_tokenID] = address(token);
}
function getTokenAddress(uint32 _id) public view returns(address) {
return tokens[_id];
}
function getBeacon() public view returns(address) {
return address(beacon);
}
function getImplementation() public view returns(address) {
return beacon.getBeacon().implementation();
}
}
And this is my Beacon contract:
// SPDX-License-Identifier: MIT
pragma solidity 0.8.7;
import "@openzeppelin/contracts/proxy/beacon/UpgradeableBeacon.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
contract TokenBeacon is Ownable {
UpgradeableBeacon immutable beacon;
address public blueprint;
//For more informations on UpgradeableBeacon: https://docs.openzeppelin.com/contracts/4.x/api/proxy#UpgradeableBeacon
constructor(address _initBlueprint) {
beacon = new UpgradeableBeacon(_initBlueprint);
blueprint = _initBlueprint;
//tx.origin let us consider the very first person that initialized the transaction
transferOwnership(tx.origin);
}
//For more info on upgradeTo: https://docs.openzeppelin.com/contracts/4.x/api/proxy#UpgradeableBeacon-upgradeTo-address-
function update(address _newBlueprint) public onlyOwner {
beacon.upgradeTo(_newBlueprint);
blueprint = _newBlueprint;
}
function getBeacon() public view returns(UpgradeableBeacon) {
return beacon;
}
}
When I call createToken function I get this error:
ProviderError: Error: Transaction reverted: function selector was not recognized and there's no fallback function
Why is that? I think that there's a problem when in the line where I do:
BeaconProxy token = new BeaconProxy(
address(beacon),
abi.encodeWithSelector(
Token(address(0)).initialize.selector,
_name,
_symbol
)
);