1

I wrote a smart contract in solidity and want to test it with hardhat, but I don't know how to solve this issue and sorry at the beginning, it could be a very long post. My smart contract looks like this:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

import "@openzeppelin/contracts/utils/math/SafeMath.sol";
import "./IBalancerVault.sol";
import "hardhat/console.sol";
import "./interfaces/IUniswapV2Router02.sol";

contract TestSwap {
    using SafeMath for uint256;
    address private owner;
    address public sushiRouter;

    constructor(
        address _sushiRouter,
    ) {
        owner = msg.sender;
        sushiRouter = _sushiRouter;
    }

    modifier onlyOwner() {
        require(msg.sender == owner);
        _;
    }

    receive() external payable {}

    function balance(address token_address) external view returns (uint256) {
        console.log("TOKEN ADDRESS:");
        console.log(token_address);
        uint256 Balance = IERC20(token_address).balanceOf(address(this));
        console.log("Token Balance: ", Balance);
        return Balance;
    }

    function swapExactTokensForTokensSushi(
        uint256 _amountIn,
        uint256 _amountOutMin, 
        address _tokenIn,
        address _tokenOut,
        uint256 deadline
    ) public returns (uint256) {
        console.log(_amountIn);
        console.log(_amountOutMin);
        console.log(_tokenIn);
        console.log(_tokenOut);
        console.log(deadline);
        require(
            IERC20(_tokenIn).approve(sushiRouter, _amountIn),
            "approve failed."
        );
        address[] memory path;
        path = new address[](2);
        path[0] = _tokenIn;
        path[1] = _tokenOut;
        uint256[] memory amounts = IUniswapV2Router02(sushiRouter)
            .swapExactTokensForTokens(
                _amountIn,
                _amountOutMin,
                path,
                address(this),
                deadline 
            );
        console.log(amounts[1]);
        return amounts[1];
    }
}

So now I want to test the swap function after funding my contract with a bit of Matic (0x0000000000000000000000000000000000001010).

const { expect } = require("chai");
const { ethers } = require("hardhat");
const {
  IERC20,
} = require("../artifacts/@openzeppelin/contracts/token/ERC20/IERC20.sol/IERC20.json");
const token_Address_wmatic = "0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270";
const token_Address_matic = "0x0000000000000000000000000000000000001010";
const router_sushi = "0x1b02dA8Cb0d097eB8D57A175b88c7D8b47997506";
const balancer_vault = "0xBA12222222228d8Ba445958a75a0704d566BF2C8";

describe("test", () => {
  let Contract, owner, addr1, addr2, addr3;

  beforeEach(async () => {
    [owner, addr1, addr2, addr3] = await ethers.getSigners();
    factory = await ethers.getContractFactory("TestSwap");
    Contract = await factory.deploy(router_sushi);
    await Flashloan.deployed();
  });

  describe("Test functions", async () => {
    it("Should test swap function", async () => {
      let addr = addr1;
      let balance_signer = await addr.getBalance();
      const gasPrice = await ethers.provider.getGasPrice();
      console.log("Gas Price: ", gasPrice);
      console.log(
        "Address 1 BEFORE: ",
        ethers.utils.formatUnits(balance_signer.toString(), 18)
      );
      let balance_contract = await Contract.balance(token_Address_matic);
      console.log("MATIC BALANCE BEFORE: ", balance_contract);
      await addr.sendTransaction({
        to: Contract.address,
        value: ethers.utils.parseUnits("100", 18), // Sends exactly 10 matic
      });
      balance_signer = await addr.getBalance();
      console.log(
        "Address 1 AFTER: ",
        ethers.utils.formatUnits(balance_signer.toString(), 18)
      );
      balance_contract = await Contract.balance(token_Address_matic);
      console.log(
        "MATIC BALANCE AFTER: ",
        balance_contract / 1_000_000_000_000_000_000
      );
      //Swap to WMATIC - Only swap 90 out of 100 to be sure and set amount outmin very low (to not revert)
      let amountIn = ethers.utils.parseUnits("90", 18);
      let amountOutMin = ethers.utils.parseUnits("10", 18);
      let tokenIn = token_Address_matic;
      let tokenOut = token_Address_wmatic;
      let deadline = 90000; //Will be added to the block.timestamp
      await expect(
        Contract.swapExactTokensForTokensQuick(
          amountIn,
          amountOutMin,
          tokenIn,
          tokenOut,
          deadline
        )
      ).to.be.revertedWith("Error1");
      await expect(
        Contract.swapExactTokensForTokensQuick(
          amountIn,
          amountOutMin,
          tokenIn,
          tokenOut,
          deadline
        )
      ).to.be.revertedWithCustomError(MyContract, "CustomError 2");
      
    });
  describe("Receive Tokens", async () => {
    it("Should send wmatic tokens", async () => {
      let addr = addr1;
      let balance_signer = await addr.getBalance();
      const gasPrice = await ethers.provider.getGasPrice();
      console.log("Gas Price: ", gasPrice);
      console.log(
        "Address 1 BEFORE: ",
        ethers.utils.formatUnits(balance_signer.toString(), 18)
      );
      let balance_contract = await Contract.balance(token_Address_matic);
      console.log("MATIC BALANCE BEFORE: ", balance_contract);
      await addr.sendTransaction({
        to: Contract.address,
        value: ethers.utils.parseUnits("100", 18), // Sends exactly 10 matic
      });
      balance_signer = await addr.getBalance();
      console.log(
        "Address 1 AFTER: ",
        ethers.utils.formatUnits(balance_signer.toString(), 18)
      );
      balance_contract = await Contract.balance(token_Address_matic);
      console.log(
        "MATIC BALANCE AFTER: ",
        balance_contract / 1_000_000_000_000_000_000
      );
      //Swap to WMATIC - Only swap 90 out of 100 to be sure and set amount outmin very low (to not revert)
      let amountIn = ethers.utils.parseUnits("90", 18);
      let amountOutMin = ethers.utils.parseUnits("10", 18);
      let tokenIn = token_Address_matic;
      let tokenOut = token_Address_wmatic;
      let deadline = 90000; //Will be added to the block.timestamp
      const gasEstimate =
        await Contract.estimateGas.swapExactTokensForTokensSushi(
          amountIn,
          amountOutMin,
          tokenIn,
          tokenOut,
          deadline
        );
      console.log(gasEstimate);

      let tx = await Flashloan.swapExactTokensForTokensSushi(
        amountIn,
        amountOutMin,
        tokenIn,
        tokenOut,
        deadline,
        { gasLimit: gasEstimate * 50 }
      );
      console.log(tx);
      console.log("Amount Out should be: ", am_out);
      balance_contract = await Contract.balance(token_Address_matic);
      console.log(
        "MATIC BALANCE AFTER: ",
        balance_contract / 1_000_000_000_000_000_000
      );
      balance_contract = await Contract.balance(token_Address_wmatic);
      console.log(
        "WMATIC BALANCE AFTER: ",
        balance_contract / 1_000_000_000_000_000_000
      );
    });
  });
});

By testing I get the error:

1) test
       Test functions
         Should test swap function:
     AssertionError: Expected transaction to be reverted with Error1, but other exception was thrown: ProviderError: Error: Transaction reverted without a reason string

and:

2) test
       Receive Tokens
         Should send wmatic tokens:
     Error: cannot estimate gas; transaction may fail or may require manual gas limit [ See: https://links.ethers.org/v5-errors-UNPREDICTABLE_GAS_LIMIT ] (reason="Error: Transaction reverted without a reason string", method="estimateGas", transaction={"from":"0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266","to":"0x58Be5Ec7F96Ef12B6d8B41611AdE2205F0AD1df7","data":"0x040e3b97000000000000000000000000000000000000000000000004e1003b28d92800000000000000000000000000000000000000000000000000008ac7230489e8000000000000000000000000000000000000000000000000000000000000000010100000000000000000000000000d500b1d8e8ef31e21c99d1db9a6444d3adf12700000000000000000000000000000000000000000000000000000000000002328","accessList":null}, error={"name":"ProviderError","code":-32603,"_isProviderError":true,"data":{"message":"Error: Transaction reverted without a reason string","data":"0x"}}, code=UNPREDICTABLE_GAS_LIMIT, version=providers/5.7.1)

Can someone help me solving this issue?

Would be amazing, I don't know what to do anymore...

Thank you!!!

1 Answer 1

1

swapExactTokensForTokensSushi function is private. You should make local unit tests for your contract before deploying to live nets.

1
  • Thanks for your answer , but I have to say, that was my mistake by inserting a older version... Actually I have set it as public and I have corrected the question. Error stys the same
    – Dani S
    Nov 5, 2022 at 8:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.