1

I have two Solidity contracts: a token contract and a token factory contract. The token factory contract is responsible for deploying various tokens. Within the token contract, I have defined mint and burn functions as external, which internally utilize _mint and _burn functions, respectively.

Here's a simplified version of my token contract:

pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

contract MyToken is ERC20 {
    constructor(string memory name, string memory symbol) ERC20(name, symbol) {}

    function mint(address to, uint256 amount) external {
        _mint(to, amount); // Internal function
    }

    function burn(address from, uint256 amount) external {
        _burn(from, amount); // Internal function
    }
}

contract TokenFactory {
    function createToken(string memory name, string memory symbol) external {
        MyToken newToken = new MyToken(name, symbol);
        // How can I securely call the internal _mint and _burn functions from here?
    }
}

My issue arises from the fact that, because I'm using external functions for minting and burning, anyone can call these functions. This creates a security concern as it allows unauthorized users to manipulate the token supply.

My question is: How can I securely call the internal _mint and _burn functions in the token factory contract? Alternatively, are there better approaches to achieve this functionality?

I appreciate any insights or suggestions. Thank you!

1 Answer 1

1

You should restrict the access of _mint and _burn to be only available to the TokenFactory contract. You can do something like this, just tailor to your logic slightly, if needed:

pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

contract MyToken is ERC20 {
    address private immutable factory;
    constructor(string memory name, string memory symbol) ERC20(name, symbol) {
        factory = msg.sender;
    }

    modifier onlyFactory {
        require(msg.sender == factory, "Sender is not the factory");
        _;
    }

    function mint(address to, uint256 amount) external onlyFactory {
        _mint(to, amount); // Internal function
    }

    function burn(address from, uint256 amount) external onlyFactory {
        _burn(from, amount); // Internal function
    }
}

contract TokenFactory {
    address private immutable owner;
    address private admin;
    constructor () {
        owner = msg.sender;
    }

    modifier onlyOwner {
        require(msg.sender == owner, "Sender is not the owner of this contract");
        _;
    }

    function setAdmin(address newAdmin) external onlyOwner {
        admin = newAdmin;
    }

    modifier auth {
        require(msg.sender == owner || msg.sender == admin, "Caller not allowed to call this restricted function");
        _;
    }

    function createToken(string memory name, string memory symbol) external {
        MyToken newToken = new MyToken(name, symbol);
        // How can I securely call the internal _mint and _burn functions from here?
    }

    function reward(MyToken targetToken, address to, uint256 amount) external auth {
        targetToken.mint(to, amount);
    }

    function punish(MyToken targetToken, address from, uint256 amount) external auth {
        targetToken.burn(from, amount);
    }
}

That way the public functions will have restricted access, and will only be available to the authorized callers.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.