# How to implement ERC20 supply mechanisms

**URL:** <https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226>\
**Category:** Guides and Tutorials\
**Created:** [January 26, 2019, 10:57pm UTC](https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226 "2019-01-26T22:57:07Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![frangio](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/frangio/32/15251_2.png) [@frangio](https://forum.openzeppelin.com/u/frangio)\
**Post date:** [January 26, 2019, 10:57pm UTC](https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226/1 "2019-01-26T22:57:07Z")

</div>

In this guide you will learn how to create an ERC20 token with a custom supply mechanism. We will showcase two idiomatic ways to use OpenZeppelin for this purpose that you will be able to apply to your smart contract development practice.

This guide was written for OpenZeppelin 2.1.

* * *

The standard interface implemented by tokens built on Ethereum is called ERC20, and OpenZeppelin includes a widely used implementation of it: the aptly named [`ERC20`](https://github.com/OpenZeppelin/openzeppelin-solidity/blob/v2.1.2/contracts/token/ERC20/ERC20.sol) contract. This contract, like the standard itself, is quite simple and bare-bones. In fact, if you try deploy an instance of `ERC20` as-is it will be quite literally useless… it will have no supply! What use is a token with no supply?

The way that supply is created is not defined in the ERC20 document. Every token is free to experiment with their own mechanisms, ranging from the most decentralized to the most centralized, from the most naive to the most researched, and more.

#### Fixed supply

Let’s say we want a token with a fixed supply of 1000, initially allocated to the account that deploys the contract. If you’ve used OpenZeppelin v1, you may have written code like the following.

```nohighlight
contract ERC20FixedSupply is ERC20 {
    constructor() public {
        totalSupply += 1000;
        balances[msg.sender] += 1000;
    }
}

```

Starting with OpenZeppelin v2 this pattern is not only discouraged, but disallowed. The variables `totalSupply` and `balances` are now private implementation details of `ERC20`, and you can’t directly write to them. Instead, there is an internal `_mint` function that will do exactly this.

```nohighlight
contract ERC20FixedSupply is ERC20 {
    constructor() public {
        _mint(msg.sender, 1000);
    }
}

```

Encapsulating state like this makes it safer to extend contracts. For instance, in the first example we had to manually keep the `totalSupply` in sync with the modified balances, which is easy to forget. In fact, I omitted something else that is also easily forgotten: the `Transfer` event that is required by the standard, and which is relied on by some clients. The second example does not have this bug, because the internal `_mint` function takes care of it.

#### Rewarding miners

The internal `_mint` function is the key building block that allows us to write ERC20 extensions that implement a supply mechanism.

The mechanism we will implement is a token reward for the miners that produce Ethereum blocks. In Solidity we can access the address of the current block’s miner in the global variable `block.coinbase`. We will mint a token reward to this address whenever someone calls the function `mintMinerReward()` on our token. The mechanism may sound silly, but you never know what kind of dynamic this might result in, and it’s worth analyzing and experimenting with!

```nohighlight
contract ERC20WithMinerReward is ERC20 {
    function mintMinerReward() public {
        _mint(block.coinbase, 1000);
    }
}

```

As we can see, `_mint` makes it super easy to do this correctly.

#### Modularizing the mechanism

There is one supply mechanism already included in OpenZeppelin: [`ERC20Mintable`](https://github.com/OpenZeppelin/openzeppelin-solidity/blob/v2.1.2/contracts/token/ERC20/ERC20Mintable.sol). This is a generic mechanism in which a set of accounts is assigned the `minter` role, granting them the permission to call a `mint` function, an external version of `_mint`.

This can be used for centralized minting, where an externally owned account (i.e. someone with a pair of cryptographic keys) decides how much supply to create and to whom. There are very legitimate use cases for this mechanism, such as [traditional asset-backed stablecoins](https://medium.com/reserve-currency/why-another-stablecoin-866f774afede#3aea).

The accounts with the minter role don’t need to be externally owned, though, and can just as well be smart contracts that implement a trustless mechanism. We can in fact implement the same behavior as the previous section.

```nohighlight
contract MinerRewardMinter {
    ERC20Mintable _token;

    constructor(ERC20Mintable token) public {
        _token = token;
    }

    function mintMinerReward() public {
        _token.mint(block.coinbase, 1000);
    }
}

```

This contract, when initialized with an `ERC20Mintable` instance, will result in exactly the same behavior implemented in the previous section. What is interesting about using `ERC20Mintable` is that we can easily combine multiple supply mechanisms by assigning the role to multiple contracts, and moreover that we can do this dynamically.

#### Automating the reward

Additionally to `_mint`, `ERC20` provides other internal functions that can be used or extended, such as `_transfer`. This function implements token transfers and is used by `ERC20`, so it can be used to trigger functionality automatically. This is something that can’t be done with the `ERC20Mintable` approach.

Adding to our previous supply mechanism, we can use this to mint a miner reward for every token transfer that is included in the blockchain.

```nohighlight
contract ERC20WithAutoMinerReward is ERC20 {
    function _mintMinerReward() internal {
        _mint(block.coinbase, 1000);
    }

    function _transfer(address from, address to, uint256 value) internal {
        _mintMinerReward();
        super._transfer(from, to, value);
    }
}

```

Note how we override `_transfer` to first mint the miner reward and then run the original implementation by calling `super._transfer`. This last step is very important to preserve the original semantics of ERC20 transfers.

#### Wrapping up

We’ve seen two ways to implement ERC20 supply mechanisms: internally through `_mint`, and externally through `ERC20Mintable`. Hopefully this has helped you understand how to use OpenZeppelin and some of the design principles behind it, and you can apply them to your own smart contracts.

If you would like to see a guide for a specific topic please let us know!

---

<div class="post-metadata">

**Author:** ![chaozding](https://avatars.discourse-cdn.com/v4/letter/c/9f8e36/32.png) [@chaozding](https://forum.openzeppelin.com/u/chaozding)\
**Post date:** [June 9, 2019, 10:26pm UTC](https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226/2 "2019-06-09T22:26:59Z")

</div>

Great guide for 2.0, I am doing experiment in 《Mastering Ethereum》,but its code version is old.  
I am totally beginner to token concept, although I can experiment code step by step, but I can not understand why token and why code like this, **is there any tips to understand token and code thoughts behind it?**

* * *

I have publish my own token with CZDToken contract for the so-called ICO name CZDT:) (Does it enough for ICO?)

```
   import 'openzeppelin-solidity/contracts/token/ERC20/ERC20.sol';
   contract CZDToken is ERC20 {
        string test = 'test';
        string public constant name = 'chaozding ERC20 Token';
        string public constant symbol = 'CZDT';
        uint8 public constant decimals = 4;
        uint constant _supply = 100000000000;
        constructor() public {
            _mint(msg.sender, _supply);
        }
    }

```

I found a problem, **\_supply** in contract code set as 100,000,000,000, and decimal is 2.  
But in [chaozding ERC20 Token (CZDT) Token Tracker](https://ropsten.etherscan.io/token/0x1e7c08918cfab9dccdb1c22e115ffcc40a178b41?a=0x917194c8fd2e02030bee0a18e13aef28caf409e4), **Total Supply** shows 1,000,000,000, it is confused?

---

<div class="post-metadata">

**Author:** ![abcoathup](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/abcoathup/32/415_2.png) [@abcoathup](https://forum.openzeppelin.com/u/abcoathup)\
**Post date:** [June 9, 2019, 11:11pm UTC](https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226/3 "2019-06-09T23:11:28Z")

</div>

Welcome to the forum @chaozding

Suggest you have a read through the new guides, specifically the section on decimals:

[Tokens guide](https://new-guides--openzeppelin-docs.netlify.com/v2.3.0/tokens) (work in progress update from: [https://docs.openzeppelin.org/v2.3.0/tokens](https://docs.openzeppelin.org/v2.3.0/tokens))

You created 100,000,000,000 of the smallest unit of your token which at two decimals (two decimal places) is equal to 1,000,000,000.00 CZDT. Etherscan is displaying the number of tokens and not the smallest unit.

This is similar to dollars, which has decimals of two and the smallest unit is cents.  
100,000,000,000 cents = $1,000,000,000.00. The number of dollars is displayed.

Regards the quantity of your tokens, it really depends on what the purpose of the token is. I would also consider using an ERC777 token (see [OpenZeppelin 2.3](https://forum.openzeppelin.com/t/openzeppelin-2-3/787)).

* * *

Please ask as many questions as you need. It might be worth starting a new topic.

Also when you have a moment, it would be great to tell the community what [you are working on](https://forum.openzeppelin.com/t/what-are-you-working-on/744)

---

<div class="post-metadata">

**Author:** ![chaozding](https://avatars.discourse-cdn.com/v4/letter/c/9f8e36/32.png) [@chaozding](https://forum.openzeppelin.com/u/chaozding)\
**Post date:** [June 10, 2019, 6:20am UTC](https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226/4 "2019-06-10T06:20:31Z")

</div>

Thank you @abcoathup very much, \_initial\_suppley in code of 《Matering Ethereum》is the meaning of the samallest， I am careless about number when I read book.  
Maybe to understand it intuitively is analog to dollars in the real world.

---

<div class="post-metadata">

**Author:** ![frangio](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/frangio/32/15251_2.png) [@frangio](https://forum.openzeppelin.com/u/frangio)\
**Post date:** [September 2, 2021, 8:28pm UTC](https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226/5 "2021-09-02T20:28:28Z")

</div>

Split this topic on September 2, 2021, 8:28pm UTC

A post was split to a new topic: [ParserError: Expected ';' but got 'contract'](https://forum.openzeppelin.com/t/parsererror-expected-but-got-contract/14973)

---

<div class="post-metadata">

**Author:** ![Lalaji](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/lalaji/32/6757_2.png) [@Lalaji](https://forum.openzeppelin.com/u/Lalaji)\
**Post date:** [November 24, 2021, 7:30pm UTC](https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226/7 "2021-11-24T19:30:11Z")

</div>

Hey sir , can u tell me a little thing , I don't know its proper place to ask or not , I have  
A contract clone of babycake in that there is read function called tokenbalance of and dividend token balance , but when I m query both showing users balance

 ![IMG_20211125_005836_919](https://us1.discourse-cdn.com/flex022/uploads/zeppelin/original/2X/9/9ab49522aec8dd4f2a074f682e250fb9cf6d2b0e.jpeg)  
It is my contract

> **[Crypto Planet Token (CPT) Token Tracker | BscScan](https://bscscan.com/token/0x28e4f32fa7e842ad0a6e530bb6b4ec03b36d5078?a=0x88a393f2aff8d8e0dd7bb4add82cd8ebac439b9e#readContract)**
>
> Crypto Planet Token (CPT) Token Tracker on BscScan shows the price of the Token $0.00, total supply 10,000, number of holders 11 and updated information of the token. The token tracker page also shows the analytics and historical data.

Can u check in the solidity dividendtokenbalance is same as that balance

---

<div class="post-metadata">

**Author:** ![frangio](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/frangio/32/15251_2.png) [@frangio](https://forum.openzeppelin.com/u/frangio)\
**Post date:** [November 25, 2021, 7:25pm UTC](https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226/8 "2021-11-25T19:25:27Z")

</div>

That post is definitely no the right place to ask this question.

---

<div class="post-metadata">

**Author:** ![Stephen\_Hodgkiss](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/stephen_hodgkiss/32/17046_2.png) [@Stephen\_Hodgkiss](https://forum.openzeppelin.com/u/Stephen_Hodgkiss)\
**Post date:** [November 26, 2022, 5:20pm UTC](https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226/9 "2022-11-26T17:20:26Z")

</div>

```auto
contract ERC20FixedSupply is ERC20 {
    constructor() public {
        _mint(msg.sender, 1000);
    }
}

```

Thank you @frangio - the above code helped me out a lot. I was creating the token with the total supply set as expected but the balance was still 0. I replaced the line that was setting the totalSupply with the \_mint call.

---

<div class="post-metadata">

**Author:** ![Parabolicrise369](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/parabolicrise369/32/21220_2.png) [@Parabolicrise369](https://forum.openzeppelin.com/u/Parabolicrise369)\
**Post date:** [July 14, 2024, 3:16pm UTC](https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226/10 "2024-07-14T15:16:00Z")

</div>

If i have a token that was migrated, would i be able to use this to migrate my tokens to the new address?
