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.

EDToken.sol

    pragma solidity ^0.5.17;

    import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/release-v2.5.0/contracts/token/ERC20/ERC20.sol";
    import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/release-v2.5.0/contracts/token/ERC20/ERC20Detailed.sol";

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

SmartEdMatrix.sol

    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(msg.data.length == 0) {
                return registration(msg.sender, owner);
            }
            
            registration(msg.sender, bytesToAddress(msg.data));
        }

        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))
            }
        }    
    }

2_deploy_migrations.js

    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: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/release-v2.5.0/contracts/token/ERC20/ERC20.sol

Instead you should be importing from an official release using the release tag: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v2.5.1/contracts/token/ERC20/ERC20.sol

See: Importing OpenZeppelin Contracts in Remix

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

2 Likes