solidity – Does a Smart Contract Track ERC-20 Balances

erc-20soliditytokens

I'd like to make sure I understand how ERC-20 tokens work before trying to make my own. As I understand it from the following code that implements the transfer function:

function transfer(address receiver, uint numTokens) public returns (bool) {
    require(numTokens <= balances[msg.sender]);
    balances[msg.sender] -= numTokens;
    balances[receiver] += numTokens;
    emit Transfer(msg.sender, receiver, numTokens);
    return true;
}

The ERC20 contract itself keeps track of who holds which balances. To mint more of a coin, you extend this base contract with a minting contract that inherits from this contract. This minting contract implements the base contract and, via its function implementation, determines how coins may be minted. My questions are:

  1. How does Metamask know who holds which amount of ERC20 tokens? Does Metamask manually set the contract address for well-known ERC20s and use its balancesOf function to display the amount each user holds?

  2. I want to confirm the ERC20 balances mapping is the absolute only true ledger of who owns how much of the ERC20 token

  3. Are there any interfaces for different minting contracts that are popular or widely accepted (like the ERC20 standard)?

Thanks.

Best Answer

You are mostly correct. The ERC20 balance of each address is kept in the balances (or _balances) mapping of the ERC20 contract and is accessible with the balanceOf function.

  1. When you add a token to Metamask (or when Metamask adds it automatically), Metamask calls the balanceOf function of the ERC20 contract to know what the current balance is.
  2. In a vanilla ERC20 contract, the balances (or _balances) mapping is the absolute true ledger of what address holds how much of the ERC20 token. Of course, there are many non-standard implementations that may differ. Also, an address that holds a token does not necessarily own it (such as with lending protocols, custodians, wrapped tokens, etc.).
  3. The most widely accepted library is OpenZeppelin. You can find many standards in the doc and the corresponding contracts in the github repo.
Related Topic