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
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())));
}
}
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') ?
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.
Your ERC20 contract has 18 decimals. If you want to send 1000 tokens then you should multiply 1000 with 10^18 (as described by the @abcoathup1000 * 10^18). So you should send 1000000000000000000000 (1000 and 18 zeros)