Transfer ERC20 on deploy (truffle migrate)

I’ve got a project with an ERC20 token that has to be separate from my actual app.
I want to transfer some of the tokens on deployment with truffle.
For some reason they’re not making it through and I have no idea why.
I get no error. Here’s my deployment file

const CoolToken = artifacts.require("CoolToken");
const CoolApp = artifacts.require("CoolApp");
module.exports = function (deployer) {
  deployer.deploy(CoolToken, "Cool", "COOL", '1000000000000000000000000');
  CoolToken.deployed().then( tokenInstance => {
      deployer.deploy(CoolApp, tokenInstance.address); // constructor takes the token contract's address as a param
      CoolApp.deployed().then( gameInstance => {
          tokenInstance.transfer(gameInstance.address, '500000000000000000000000');

After deploy I use truffle console to get the app instance (i = await CoolApp.deployed())
Then I call a function that checks the balance of the app contract, and it returns zero.


The contract code:

address public coolTokens;
constructor(address tokenAddress) public {
    coolTokens = tokenAddress;
function getContractCoolBalance() public view returns (uint256) {
    return ERC20(coolTokens).balanceOf(address(this));

I’ve even tried doing it manually after deployment by setting an instance of the token contract and calling transfer on the app contract’s address, but still zero. What am I missing?

1 Like

Hi @poshdan,

I find it much easier to read migrations using async/await, so I recommend using that.

I created a simple example (based on Example on how to use ERC20 token in another contract)


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

import "@openzeppelin/contracts/GSN/Context.sol";
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.
contract SimpleToken is Context, ERC20 {

     * @dev Constructor that gives _msgSender() all of existing tokens.
    constructor () public ERC20("SimpleToken", "SIM") {
        _mint(_msgSender(), 10000 * (10 ** uint256(decimals())));


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

contract TokenReceiver {


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

module.exports = async function (deployer) {
  await deployer.deploy(SimpleToken);
  const token = await SimpleToken.deployed();

  await deployer.deploy(TokenReceiver, token.address);
  const receiver = await TokenReceiver.deployed();

  await token.transfer(receiver.address, "100000000");

Truffle Develop

Deploy the contracts using migrations and then check the balance manually

$ npx truffle develop
Truffle Develop started at

truffle(develop)> migrate

Compiling your contracts...


   Deploying 'Migrations'


   Deploying 'SimpleToken'
   Deploying 'TokenReceiver'

truffle(develop)> token = await SimpleToken.deployed()
truffle(develop)> receiver = await TokenReceiver.deployed()
truffle(develop)> (await token.balanceOf(receiver.address)).toString()

This worked. Thank you!
I’m not sure what all went wrong for me previously, I have tried some async await operations but it had really odd results. I may have been a bit too tired to code as well.

I didn’t have this exact simple code, and I noticed today that the tokens weren’t even being minted, which was really odd. Could it have been the choice of apostrophes to pass the constructor argument instead of quotations marks? I really don’t know javascript.

Either way, it’s good now. Thanks again

1 Like

Hi @poshdan,

I wasn’t exactly sure what was causing the issue, I assume it was with the promises in your migrations script, which is why I found it easier just to create an example with awync/await.