I have an ERC20 token that I would like another smart contract (lets call it Manager) to be able to mint to the users of the dapp. I am assuming, I should restrict the mint function to only be execute by the Manager smart contract otherwise anyone can just go to the token address and mint from etherscan. First of all, is that assumption correct?
Based on that assumption, my token contract looks like this:
contract XYZToken is ERC20, ERC20Burnable, Ownable, {
constructor() ERC20("XYZToken", "XYZ") ERC20Permit("XYZToken") {}
function mint(address to, uint256 amount) external onlyOwner {
_mint(to, amount);
}
...
Then in Manager contract, I would need the address of this token to be able to mint so I am passing that in the constructor
contract Manager {
XYZToken xyzToken;
constructor(address _xyzToken) {
xyzToken = XYZToken(_lendToken);
}
function mintTokens(uint256 _amount) external nonReentrant {
xyzToken.mint(msg.sender, _amount);
}
Finally, to make the Manager contract owner of the Token contract, I have to run this deployment script after deployment of both contracts
const manager = await ethers.getContract("Manager");
const token = await ethers.getContract("XYZToken");
await token.transferOwnership(manager.address);
Is this the right way to set up the minting of tokens through another smart contract or is there a better design pattern for this approach?
Would it be better to use a modifier onlyManager
instead of onlyOwner
on token mint function? then I have to pass the Manager contract address to the token after deployment. At the same time, the Manager needs the address of the token during its deployment so it becomes this cyclic dependency that won't allow deployment to happen. I guess another approach would be to set the manager public property on the token after deployment similar to the transferOwnership
.
Finally, should the Manager be minting token through the single reference of the token address passed to it or instantiate the token object using the new
operator?
Overall, I am looking for suggestions on the correct design pattern or approach for this use case. Any help is appreciated!