Understanding decimals for ERC20 token creation?

Hi people,

I am experimenting with ERC20 tokens and want to set a supply with 18 decimals. And I couldn’t understand the math behind it. Can someone explain it please?

For example, if I wanna create a supply with 10000 Tokens, what is the math behind it?

Should I do 10000 / (10 ** 18) or 10000 * 10 ** 18? And what value should I pass for the _mint function to create 10000 tokens?

I know the math is simple but bear with me. I am poor at calculations :grimacing:

Thanks.

1 Like

Hi @manolingam,

Please see the OpenZeppelin documentation on decimals which should explain the math:
https://docs.openzeppelin.com/contracts/2.x/tokens#a-note-on-decimals

TLDR: Decimals are for display purposes, calculations are done in the base units for a token. So you need 10000 * 10 ** 18 (token base units) for 10000 tokens.

See an example below:

SimpleToken

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

/**
 * @title SimpleToken
 * @dev Very simple ERC20 Token example, where all tokens are pre-assigned to the creator.
 * Note they can later distribute these tokens as they wish using `transfer` and other
 * `ERC20` functions.
 */
contract SimpleToken is Context, ERC20, ERC20Detailed {

    /**
     * @dev Constructor that gives _msgSender() all of existing tokens.
     */
    constructor () public ERC20Detailed("SimpleToken", "SIM", 18) {
        _mint(_msgSender(), 10000 * (10 ** uint256(decimals())));
    }
}
1 Like

Thanks @abcoathup. Yes, I checked the documentation too.

Okay. If I wanna transfer 100 tokens, then should I call the transfer function with 100 * 10 ** 18?

1 Like

Yes. All operations in the smart contract use the token base units, so to transfer 100 tokens you transfer 100 * 10 ** 18 token base units.

1 Like

Since all operations needs to be multiplied by ten to the power of decimals, should we manually update amount from OpenZeppelin contracts to amount * 10 ** 18 for the functions in ERC20.sol ? or Can I send the transactions using web3.utils.toWei(amount, 'ether') ?

1 Like

Hi @manolingam,

We need to use amounts in token base units when we call ERC20 functions.

If we updated the amount used in the contract to be amount * 10 ** 18 it would be the equivalent of having decimals of zero, or using the example of dollars and cents, it would be the equivalent of only using dollars.

Whilst you should be able to use web3.utils.toWei(amount, 'ether') it is less clear for someone reading your code, so I would suggest not doing that.

1 Like