1

I have the following contract that is already deployed (pasted below). I can see where the constructor() method is doing an emit Transfer from the 0x0 (zero) address to the deployer address in order to mint the initial supply, but how would I use emit Transfer in another function to distribute tokens via mint OR how would I use the transferFrom() to mint new tokens with the same contract to the deployer address?

Couldn't I just do transferFrom(0x0, msg.sender, SUPPLY_AMOUNT)? Trying this, but keep getting an error.

I'm familiar with Remix, so if there's a way to do it there, I can probably get it.

Here's the contract code:

pragma solidity ^0.8.18;

contract ERC20Basic {
  function totalSupply() public view returns (uint256);
  function balanceOf(address who) public view returns (uint256);
  function transfer(address to, uint256 value) public returns (bool);
  event Transfer(address indexed from, address indexed to, uint256 value);
}

library SafeMath {

  function mul(uint256 a, uint256 b) internal pure returns (uint256 c) {
    if (a == 0) {
      return 0;
    }
    c = a * b;
    assert(c / a == b);
    return c;
  }

  function div(uint256 a, uint256 b) internal pure returns (uint256) {
    // assert(b > 0); // Solidity automatically throws when dividing by 0
    // uint256 c = a / b;
    // assert(a == b * c + a % b); // There is no case in which this doesn't hold
    return a / b;
  }

  function sub(uint256 a, uint256 b) internal pure returns (uint256) {
    assert(b <= a);
    return a - b;
  }

  function add(uint256 a, uint256 b) internal pure returns (uint256 c) {
    c = a + b;
    assert(c >= a);
    return c;
  }
}

contract BasicToken is ERC20Basic {
  using SafeMath for uint256;

  mapping(address => uint256) balances;

  uint256 totalSupply_;

  function totalSupply() public view returns (uint256) {
    return totalSupply_;
  }

  function transfer(address _to, uint256 _value) public returns (bool) {
    require(_to != address(0));
    require(_value <= balances[msg.sender]);

    balances[msg.sender] = balances[msg.sender].sub(_value);
    balances[_to] = balances[_to].add(_value);
    emit Transfer(msg.sender, _to, _value);
    return true;
  }

  function balanceOf(address _owner) public view returns (uint256) {
    return balances[_owner];
  }

}

contract ERC20 is ERC20Basic {
  function allowance(address owner, address spender)
    public view returns (uint256);

  function transferFrom(address from, address to, uint256 value)
    public returns (bool);

  function approve(address spender, uint256 value) public returns (bool);
  event Approval(
    address indexed owner,
    address indexed spender,
    uint256 value
  );
}

contract StandardToken is ERC20, BasicToken {

  mapping (address => mapping (address => uint256)) internal allowed;

  function transferFrom(
    address _from,
    address _to,
    uint256 _value
  )
    public
    returns (bool)
  {
    require(_to != address(0));
    require(_value <= balances[_from]);
    require(_value <= allowed[_from][msg.sender]);

    balances[_from] = balances[_from].sub(_value);
    balances[_to] = balances[_to].add(_value);
    allowed[_from][msg.sender] = allowed[_from][msg.sender].sub(_value);
    emit Transfer(_from, _to, _value);
    return true;
  }

  function approve(address _spender, uint256 _value) public returns (bool) {
    allowed[msg.sender][_spender] = _value;
    emit Approval(msg.sender, _spender, _value);
    return true;
  }

  function allowance(
    address _owner,
    address _spender
   )
    public
    view
    returns (uint256)
  {
    return allowed[_owner][_spender];
  }

  function increaseApproval(
    address _spender,
    uint _addedValue
  )
    public
    returns (bool)
  {
    allowed[msg.sender][_spender] = (
      allowed[msg.sender][_spender].add(_addedValue));
    emit Approval(msg.sender, _spender, allowed[msg.sender][_spender]);
    return true;
  }

  function decreaseApproval(
    address _spender,
    uint _subtractedValue
  )
    public
    returns (bool)
  {
    uint oldValue = allowed[msg.sender][_spender];
    if (_subtractedValue > oldValue) {
      allowed[msg.sender][_spender] = 0;
    } else {
      allowed[msg.sender][_spender] = oldValue.sub(_subtractedValue);
    }
    emit Approval(msg.sender, _spender, allowed[msg.sender][_spender]);
    return true;
  }

}

contract MYTOKEN is StandardToken {

  string public constant name = "MYTOKEN"; // solium-disable-line uppercase
  string public constant symbol = "MYTOKEN"; // solium-disable-line uppercase
  uint8 public constant decimals = 18; // solium-disable-line uppercase

  uint256 public constant INITIAL_SUPPLY = 100000000 * (10 ** uint256(decimals));

  constructor() public {
    totalSupply_ = INITIAL_SUPPLY;
    balances[msg.sender] = INITIAL_SUPPLY;
    emit Transfer(0x0, msg.sender, INITIAL_SUPPLY);
  }

}

2 Answers 2

1

The line:

emit Transfer(0x0, msg.sender, INITIAL_SUPPLY);

is emitting and event Transfer, its content does not have any effect on the blockchain. It only uses as a notification mechanism to off-chain code (for example, a webapp listening to this to show user about the event).

The only 2 ways you can mint token are:

  1. Via the _mint function if that can be accessed by a public function and the token implements it (mintable) ERC20 Openzeppelin
  2. Change the balances[addr] and totalSupply_ directly (which is what happens in the above constructor).

Because you cannot call the constructor of deployed contract and there are no ways to achieve any of the above methods, the answer to your question is it's not possible. You must implement a new token or deploy a new instance of the contract to receive the tokens.

0

Like minhhn2910 said , since you don't have a public or external mint function, you cannot create more tokens. Your INITIAL_SUPPLY is your maximum and final totalSupply_ (since you cannot burn nor send to the 0 address neither).

The only thing you can do is manually distribute tokens from the deployer address, or have the deployer address allow an other address to distribute its tokens on its behalf.

On top of that there are quite a lot of things to say about this contract:

  • Some bad practices (constant variables are CAPITAL_CASE, ERC20 metada shouldn't be hardcoded but given as constructor input ...)
  • missing IERC165 and IERC20...
  • When using versions greater than 0.8 you don't need SafeMaths library since overflow and underflow checks are integrated.
  • Over splitting functionalities in contracts isn't recommended and
  • Contracts that define function headers but don't implement them are generally defined as Interfaces.

Your Answer

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

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