3

I have deployed an erc20 contract (very old version running of open zeplins mintable token contract on solidity 0.4.18)

calling the 'mint', 'total supply', 'finish minting' functions work fine but when i call the "transfer" function i get

Mint tokens to user1:
 Error: Transaction reverted without a reason string
  at <UnrecognizedContract>.<unknown> (0x5fbdb2315678afecb367f032d93f642f64180aa3)
  at async EthModule._estimateGasAction (node_modules/hardhat/src/internal/hardhat-network/provider/modules/eth.ts:425:7)
  at async HardhatNetworkProvider.request (node_modules/hardhat/src/internal/hardhat-network/provider/provider.ts:117:18)
  at async EthersProviderWrapper.send (node_modules/@nomiclabs/hardhat-ethers/src/internal/ethers-provider-wrapper.ts:13:20)

I can see from the console logs that the tokens are minted an exist at the address

import { expect } from 'chai';
import { ethers as Ethers } from 'ethers';
import { ethers, waffle } from 'hardhat';
import mtArtifacts from '../artifacts/contracts/mtToken.sol/mtToken.json';
import { mtToken } from '../typechain-types/mtToken';

const { deployContract } = waffle;

describe('Greeter', function () {
  let mt: mtToken;
  let owner: Ethers.Signer;
  let user1: Ethers.Signer;
  let user2: Ethers.Signer;

  this.beforeAll(async () => {
    const signers = await ethers.getSigners();
    owner = signers[0];
    user1 = signers[1];
    user2 = signers[2];

    mt = (await deployContract(owner, mtArtifacts)) as mtToken;

    const initialCount = await mt.name();
    expect(initialCount).to.eq('My Token');

    console.log("Owner balance", ethers.utils.formatEther(await owner.getBalance()))
    console.log("User1 balance", ethers.utils.formatEther(await user1.getBalance()))
    console.log("User2 balance", ethers.utils.formatEther(await user2.getBalance()))

  });

  it('Mint tokens to user1', async function () {
    const user1Address = await user1.getAddress();
    const user2Address = await user2.getAddress();

    await mt.mint(user1Address, 1000000);
    const balanceUser1 = await mt.balanceOf(user1Address);
    const balanceUser2 = await mt.balanceOf(user2Address);

    console.log("User1 mt balance", balanceUser1)
    console.log("User2 mt balance", balanceUser2)

    console.log(await mt.totalSupply())
    console.log(await mt.decimals())
    console.log(await mt.finishMinting())


    await mt.connect(user1).transfer(user2Address, 500000, {
      gasLimit: 30000000,
      gasPrice: 908478342,
    });        
  });
});
Jay P
  • 596
  • 7
  • 23

1 Answers1

1

To transfer tokens the sender must approve his address first:

await mt.connect(user1).approve(user1.address, 500000);

Then you can send his tokens

await mt.connect(user1).transfer(user2Address, 500000, {
gasLimit: 30000000,
gasPrice: 908478342,
});      

Keep in mind that after you transfer the allowance of user1 decreases to 0, so to transfer again you must approve one more time.

Dexes usually make users approve near-infinite tokens to avoid this issue