ERC20: Transferring token from another smart contract errors with transfer amount exceeds balance

I am following this guide to transfer token from another smart contract. But I am getting transfer amount exceeds balance error while transfer token from another smart contract.


    pragma solidity ^0.5.17;

    import "";
    import "";

    contract EDToken is ERC20, ERC20Detailed {
        constructor() ERC20Detailed("SampleTest", "SAMTEST", 18) public {
            _mint(msg.sender, 5000000 * 10 ** 18);


    pragma solidity >=0.4.23 <0.6.0;

    interface IERC20 {
        function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);

    contract SmartEdMatrix {
        address public owner;
        IERC20 private _token;
        uint8 public constant LAST_LEVEL = 12;

        mapping(uint8 => uint) public levelPrice;
        constructor(address ownerAddress, IERC20 token) public {
            levelPrice[1] = 5 * 10 ** 18;
            for (uint8 i = 2; i <= LAST_LEVEL; i++) {
                levelPrice[i] = levelPrice[i-1] * 2;
            owner = ownerAddress;
            _token = token;
        function() external payable {
            if( == 0) {
                return registration(msg.sender, owner);
            registration(msg.sender, bytesToAddress(;

        function registrationExt(address referrerAddress) external payable {
            registration(msg.sender, referrerAddress);
        function registration(address userAddress, address referrerAddress) private {
            _token.transferFrom(userAddress, referrerAddress, levelPrice[1]);

        function bytesToAddress(bytes memory bys) private pure returns (address addr) {
            assembly {
                addr := mload(add(bys, 20))


    const EDToken = artifacts.require('EDToken');
    const SmartEdMatrix = artifacts.require('SmartEdMatrix');

    module.exports = async function (deployer) {
      await deployer.deploy(EDToken);
      const token = await EDToken.deployed();
      const accounts = await web3.eth.getAccounts();
      const owner = accounts[0];
      await deployer.deploy(SmartEdMatrix, owner, token.address);

truffle console

       let token = await EDToken.deployed()
        let mlm = await SmartEdMatrix.deployed()
    var accounts = await web3.eth.getAccounts()
    let tokenOwner = accounts[0]
    let mlmRootAddress = tokenOwner
    let mlmContractAddr = '0x1137e7feE2506628C1C8C2074134876cD10d14Ba' //Copied from console. This is deployed contract address of **SmartEdMatrix**
    let firstUser = accounts[1]
    numberOfTokensToSend = (5*10**18).toString()
    token.approve(mlmContractAddr, numberOfTokensToSend, {from: firstUser})
    token.allowance(firstUser, mlmContractAddr)
    token = parseInt('4563918244f40000', 16)
    mlm.registrationExt(mlmRootAddress, {from: firstUser}) 

But I am getting the following error,
Error: Returned error: VM Exception while processing transaction: revert ERC20: transfer amount exceeds balance -- Reason given: ERC20: transfer amount exceeds balance. at PromiEvent (/home/css/.nvm/versions/node/v8.16.2/lib/node_modules/truffle/build/webpack:/packages/contract/lib/promievent.js:9:1)

Please help me to fix this issue. I don’t know what mistake I am making.

1 Like

Emmm, It seems like the caller does not have enough EDToken, I think after deploying the contract, only contract owner has EDToken, and I do not find when user1 gets EDToken, has owner transferred token to user1?

1 Like

Hi @selv,

As per @skyge firstUser (accounts[1]) appears to have a balance of zero tokens.
To resolve, you should be using an account which holds tokens.

I noticed that you are importing from a branch:

Instead you should be importing from an official release using the release tag:

See: Importing OpenZeppelin Contracts in Remix

@Skyge @abcoathup Yes. I am sorry. It is my careless mistake. Thank you very much for helping.