I want to create a clone factory, that will initialize ERC20 tokens. I saw some examples for older solidity versions (0.5) and it worked there. Back then was ERC20Detailed
contract that could be initialized. With solidity ^0.8.0 it doesn't work anymore or I am doing something wrong.
Here are my contracts:
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/proxy/utils/Initializable.sol";
import "@openzeppelin/contracts/proxy/Clones.sol";
contract TokenFactory{
address immutable tokenImplementation;
constructor () {
tokenImplementation = address(new Token());
}
function createToken(string calldata name, string calldata symbol, uint8 decimals, uint256 initialSupply, address owner, address[] memory airdropDestinations, uint256[] memory airdropValues) external returns (address){
address clone = Clones.clone(tokenImplementation);
Token(clone).initialize(name, symbol, decimals, initialSupply, owner, airdropDestinations, airdropValues);
return clone;
}
}
contract Token is Initializable, ERC20 {
uint8 private _decimals;
string private _name;
string private _symbol;
address private _owner;
function initialize(string memory name, string memory symbol, uint8 decimals_, uint256 supply, address owner, address[] memory airdropDestinations, uint256[] memory airdropValues) public initializer{
require(supply > 0);
ERC20.initialize(name, symbol);
_name = name;
_decimals = decimals_;
_owner = owner;
_mint(owner, supply);
_airdrop(airdropDestinations, airdropValues);
}
function decimals() public view virtual override returns (uint8) {
return _decimals;
}
function _airdrop(address[] memory destinations, uint256[] memory values) private {
uint256 i = 0;
while (i < destinations.length) {
_transfer(_owner, destinations[i], values[i]);
i += 1;
}
}
}
I am getting an error that ERC20 is not initializable, which is understandable, because it doesn't have initialize
method. Anyway, if I skip initializing it, then the will be an error that I need to call ERC20 constructor, which I don't need to.