How to resolve "Warning: Could not decode event!"

Viewed 428

I have a smart contract for sending money user-to-user.

In this smart contract, I pass the smart contract address from the Kovan network when the user selects a coin.

In this case, I pass the ChainLink contract address to my contract for sending the Chain Link token to the user.

This is ChainLink contract address in the Kovan network: 0xa36085f69e2889c224210f603d836748e7dc0088.

Now I want to test contract functions with this code:

const assert = require("assert");

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

contract("Dex", (accounts) => {

    let dex;
    let contractOwner = null;
    let buyer = null;

    beforeEach(async () => {
        contractOwner = accounts[0];
        buyer = accounts[1];

        dex = await Dex.new();
        contractOwner = accounts[0];
        // sometimes you need to test a user except contract owner
        buyer = accounts[1];
    });

    // it("Add tokens and contract address Success", async () => {

    //     const tokenInfo = await dex.getTokenContractAddress("USDT");

    //     assert(tokenInfo == "0xdac17f958d2ee523a2206206994597c13d831ec7");
    // })

    // it("Add Token", async () => {

    //     await dex.addToken(web3.utils.fromAscii("LINK"), "0xa36085f69e2889c224210f603d836748e7dc0088", "0xa36085f69e2889c224210f603d836748e7dc0088")


    // })
    it("Deposit", async () => {

        await dex.deposit("0xa36085f69e2889c224210f603d836748e7dc0088", "0x5226a51522C23CcBEFd04a2d4C6c8e281eD1d680", "0xB643992c9fBcb1Cb06b6C9eb278b2ac35e6a2711", 1,
            // you were missing this
            { from: accounts[0] });

    })



})

I Using Truffle in Project:

Truffle Config:

const HDWalletProvider = require('@truffle/hdwallet-provider');

const fs = require('fs');
const mnemonic = fs.readFileSync(".secret").toString().trim();
const secrets = JSON.parse(
  fs.readFileSync('.secrets.json').toString().trim()
);

module.exports = {

  networks: {
    kovan: {
      networkCheckTimeout: 10000,
      provider: () => {
         return new HDWalletProvider(
          mnemonic,
           `https://kovan.infura.io/v3/1461728202954c07bd5ed5308641a054`,
           0,
           20
         );
      },
      network_id: "42",
   },
  },

  // Set default mocha options here, use special reporters, etc.
  mocha: {
  
  },

  // Configure your compilers
  compilers: {
    solc: {
      version: "0.8.10", 
      docker: false, 
      settings: { 
        optimizer: {
          enabled: false,
          runs: 200
        },
        evmVersion: "byzantium"
      }
    }
  },
};

My Contract:

  // SPDX-License-Identifier: MIT
pragma solidity >=0.4.22 <0.9.0;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";

// import "./UserCoins.sol";

contract Dex {
    event Approval(
        address indexed tokenOwner,
        address indexed spender,
        uint256 tokens
    );
    event Transfer(address indexed from, address indexed to, uint256 tokens);

    constructor() {}

    function deposit(
        address ticker,
     

   address sender,
        address recipient,
        uint256 amount
    ) external payable {
        IERC20 token = IERC20(ticker);
        IERC20(ticker).approve(sender, amount);
        // Transfer Token To User
        token.transferFrom(sender, recipient, amount);
        emit Transfer(sender, recipient, amount);
    }

}

it shows me this error:

Warning: Could not decode event!
execution failed due to an exception. Reverted

How can I solve this problem?

1 Answers
function deposit(address ticker,address sender,address recipient,uint256 amount
                ) 
                external payable 

this function takes 4 args, you passed all the parameters but since it is payable, you have to also make sure from which account you are calling, so you need to add 5th parameter to the function:

await dex.deposit("0xa36085f69e2889c224210f603d836748e7dc0088", "0x5226a51522C23CcBEFd04a2d4C6c8e281eD1d680", "0xB643992c9fBcb1Cb06b6C9eb278b2ac35e6a2711", "1",
// you were missing this
{from:accounts[0])

 

In truffle test suite, when you create the contract, it passes the accounts as the first argument to the callback. You have to define accounts in before statement so when you run the tests those will be available on top level.

contract("Dex", (accounts) => {
  let contractOwner = null;
  let buyer = null;
  let _contract = null;


  before(async () => {
      // Instead of Dex.new() try Dex.deployed()
      // I am not sure if "new()" is still supported
      _contract = await Dex.deployed();
      contractOwner = accounts[0];
      // sometimes you need to test a user except contract owner
      buyer = accounts[1];
  });

}

You need to approve

Inside ERC20.sol you are calling this:

function transferFrom(
        address sender,
        address recipient,
        uint256 amount
    ) public virtual override returns (bool) {
        uint256 currentAllowance = _allowances[sender][_msgSender()];
        if (currentAllowance != type(uint256).max) {
            require(currentAllowance >= amount, "ERC20: transfer amount exceeds allowance");
            unchecked {
                _approve(sender, _msgSender(), currentAllowance - amount);
            }
        }  
        _transfer(sender, recipient, amount);

        return true;
    }

So you want DEX to transfer coin from another contract. So this another contract has to approve this transaction first. So I need to have another contract's address to be able to call approve

Related