Solidity – How Can Mock ERC20 in Truffle Test Suite?

erc-20soliditytesttruffletruffle-test

I want to test my contract using truffle test which required a mock ERC20.

I've found this example in Github and also this thread.

const ERC20 = artifacts.require("ERC20");

I've tried but got

Error: Could not find artifacts for ERC20 from any sources

How do I use ERC20 artifact from the truffle build-in test suite like so?

Or is there anyways to achieve the goal without needing to add an actual ERC20 contract to the project?

Best Answer

Take a look at the OpenZeppelin presets, follow this link for the ERC-20 ones.

EDIT : Giving you an example on how to use it (assuming Openzeppelin v4) :

First import the preset file, ex :

pragma solidity ^0.8.9;

import "@openzeppelin/contracts/token/ERC20/presets/ERC20PresetFixedSupply.sol";

contract myContract {
    // your contract logic
}

Running :

truffle compile

Will produce the different artifacts :

enter image description here

If you want the Mock ERC20 to be deployed automatically (not only when running tests) you will need to add an entry to your migration file.

var myContract = artifacts.require("myContract");
var ERC20PresetFixedSupply = artifacts.require("ERC20PresetFixedSupply");

module.exports = function (deployer, network, accounts) {
  deployer.deploy(myContract);
  deployer.deploy(
    ERC20PresetFixedSupply,
    "Mock ERC20",
    "M20",
    10000000000,
    accounts[0]
  );
};

In order to import it and use it inside your test file you could do something similar to this (assuming the mock ERC20 contract was automatically deployed when migrating) :

const myContract = artifacts.require("myContract");
const ERC20PresetFixedSupply = artifacts.require("ERC20PresetFixedSupply");

contract("myContract", (accounts) => {
  it("...should work.", async () => {
    const myContractInstace = await myContract.deployed();
    const ERC20Instance = await ERC20PresetFixedSupply.deployed();

    const symbol = await ERC20Instance.symbol();

    assert.equal(symbol, "M20", "invalid ERC20 Symbol");
  });
});

If you do not want to deploy your mock ERC20 contract by default (which makes perfect sense as you could be using it only for test purposes..) this example might be more usefull :

const myContract = artifacts.require("myContract");
const ERC20PresetFixedSupply = artifacts.require("ERC20PresetFixedSupply");

contract("myContract", (accounts) => {
  let ERC20Instance = null;

  it("...should deploy the ERC20 mock", async () => {
    ERC20Instance = await ERC20PresetFixedSupply.new(
      "Mock ERC20",
      "M20",
      100000000000,
      accounts[0]
    );
  });

  it("...should work.", async () => {
    const myContractInstace = await myContract.deployed();
    const symbol = await ERC20Instance.symbol();
    assert.equal(symbol, "M20", "invalid ERC20 Symbol");
  });
});
Related Topic