Simple ERC20 token example

Simple ERC20 token example.

:warning: The following code has not been tested nor audited.
Seek appropriate advice on regulatory compliance and your solution should have appropriate testing and auditing

Recommend reading: Points to consider when creating a fungible token (ERC20, ERC777)

:exclamation: There is an open issue to add a fixed supply ERC20 preset: https://github.com/OpenZeppelin/openzeppelin-contracts/issues/2377

This example smart contract merely sets a name, symbol and intial supply. All tokens are pre-assigned to the creator using the internal mint function.

SimpleToken.sol

// contracts/SimpleToken.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.2;

import "@openzeppelin/contracts/token/ERC20/ERC20.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.
 * Based on https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v2.5.1/contracts/examples/SimpleToken.sol
 */
contract SimpleToken is ERC20 {
    /**
     * @dev Constructor that gives msg.sender all of existing tokens.
     */
    constructor(
        string memory name,
        string memory symbol,
        uint256 initialSupply
    ) public ERC20(name, symbol) {
        _mint(msg.sender, initialSupply);
    }
}

Migration (Truffle)

2_deploy.js

// migrations/2_deploy.js
const SimpleToken = artifacts.require('SimpleToken');

module.exports = async function (deployer) {
  await deployer.deploy(SimpleToken, 'SimpleToken', 'SIM', '10000000000000000000000');
};

Test

SimpleToken.test.js

// test/SimpleToken.test.js
// SPDX-License-Identifier: MIT

// Based on https://github.com/OpenZeppelin/openzeppelin-solidity/blob/v2.5.1/test/examples/SimpleToken.test.js

const { expect } = require('chai');

// Import utilities from Test Helpers
const { BN, expectEvent, expectRevert, constants } = require('@openzeppelin/test-helpers');

// Load compiled artifacts
const SimpleToken = artifacts.require('SimpleToken');

// Start test block
contract('SimpleToken', function ([ creator, other ]) {

  const NAME = 'SimpleToken';
  const SYMBOL = 'SIM';
  const TOTAL_SUPPLY = new BN('10000000000000000000000');

  beforeEach(async function () {
    this.token = await SimpleToken.new(NAME, SYMBOL, TOTAL_SUPPLY, { from: creator });
  });

  it('retrieve returns a value previously stored', async function () {
    // Use large integer comparisons
    expect(await this.token.totalSupply()).to.be.bignumber.equal(TOTAL_SUPPLY);
  });

  it('has a name', async function () {
    expect(await this.token.name()).to.be.equal(NAME);
  });

  it('has a symbol', async function () {
    expect(await this.token.symbol()).to.be.equal(SYMBOL);
  });

  it('assigns the initial total supply to the creator', async function () {
    expect(await this.token.balanceOf(creator)).to.be.bignumber.equal(TOTAL_SUPPLY);
  });
});

Crowdsale

If you are looking for a crowdsale example, see: Simple ERC20 Crowdsale.

2 Likes

@abcoathup this is great! I actually managed to successfully write 5 tests last night after 10 painful days of mental brincsmanship. Your example is extremely helpul – i will take a good look at these. Thank you so much!!

1 Like

Tried this, caught the ^0.8.0 error...

Now throws a constructor error..

Hi, welcome! :wave:

The case that shows above uses the compiler version of 0.6.x, but the latest version of the dependency @openzeppelin/contracts uses 0.8.x, so I think you should run this command to install a right dependency:

npm i @openzeppelin/contracts@3.4.0
// contracts/SimpleToken.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC20/ERC20.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.
 * Based on https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v2.5.1/contracts/examples/SimpleToken.sol
 */
contract SimpleToken is ERC20 {
    /**
     * @dev Constructor that gives msg.sender all of existing tokens.
     */
    constructor(string memory name, string memory symbol, uint256 initialSupply) ERC20(name, symbol) {
      _mint(msg.sender, initialSupply);

    }
}

There's the update for you

also launched on Rinkeby...

Did you start your local blockchain?
I was getting the same error, then configured the truffle-config.js and started Ganache.

Yeah I got this, tossed it on Rinkeby before the faucet shut off. Just needed to update the constructor to the 0.8.x standards.

this : new BN('10000000000000000000000'); still gives error !!

 Error: Number can only safely store up to 53 bits