reactjsethereumweb3jswagmi

USDT transfer - The contract function "transfer" returned no data ("0x")


I'm using wagmi and viem to call usdt contract. I want to transfer usdt from one address to another. I get this error:

App.jsx:51 ContractFunctionExecutionError: The contract function "transfer" returned no data ("0x").

This could be due to any of the following:

Contract Call: address: 0xdAC17F958D2ee523a2206206994597C13D831ec7 function: transfer(address recipient, uint256 amount) args: (0x04dAb01aA15Dc4e57910420f7464bFC68579b2d2, 10000000) sender: 0x00d2ADa3365e40C05E8772e58B9aAcf356F3E474

Docs: https://viem.sh/docs/contract/simulateContract.html Version: viem@1.2.15 at getContractError (getContractError.ts:55:10) at simulateContract (simulateContract.ts:159:11) at async prepareWriteContract (chunk-LAFZBYO7.js:2078:31) at async writeContract (chunk-LAFZBYO7.js:2354:17)

This is the minimum repro, you will need to npm install @web3modal/ethereum @web3modal/react wagmi viem.

Here is this snippet too to create a vite project quickly: npm create vite@latest viem --template react

import {
  EthereumClient,
  w3mConnectors,
  w3mProvider,
} from "@web3modal/ethereum";
import { Web3Modal } from "@web3modal/react";
import { configureChains, createConfig, WagmiConfig } from "wagmi";
import { mainnet } from "wagmi/chains";
import { Web3Button } from "@web3modal/react";
import { useContractWrite, erc20ABI } from "wagmi";
import { parseUnits } from "viem";
import { useState } from "react";

const chains = [mainnet];
const projectId = "ef4a2eaeff8be83c88ffd2dc3850a66c";

const { publicClient } = configureChains(chains, [w3mProvider({ projectId })]);
const wagmiConfig = createConfig({
  autoConnect: true,
  connectors: w3mConnectors({ projectId, chains }),
  publicClient,
});
const ethereumClient = new EthereumClient(wagmiConfig, chains);

function App() {
  return (
    <>
      <WagmiConfig config={wagmiConfig}>
        <Web3Button />
        <br />
        <br />
        <SendUsdt />
      </WagmiConfig>

      <Web3Modal projectId={projectId} ethereumClient={ethereumClient} />
    </>
  );
}

function SendUsdt() {
  const [amount, setAmount] = useState(0);

  const { write } = useContractWrite({
    // usdt contract address
    address: "0xC230abdFA22e563C7cD6435b24C15Fa9B913ccc2",
    abi: erc20ABI,
    functionName: "transfer",
    args: [
      "0x04dAb01aA15Dc4e57910420f7464bFC68579b2d2",
      parseUnits(`${amount}`, 6),
    ],
  });

  return (
    <>
      <input type="number" onChange={(e) => setAmount(e.target.value)} />
      <button onClick={() => write()}>Transfer</button>
    </>
  );
}

export default App;

Solution

  • From https://github.com/wagmi-dev/wagmi/issues/2749#issuecomment-1638200817

    "USDTs ABI does not exactly follow the erc20ABI (see below). Make sure you either use the correct ABI."

    [
        {
            "constant": false,
            "inputs": [
                {
                    "name": "_to",
                    "type": "address"
                },
                {
                    "name": "_value",
                    "type": "uint256"
                }
            ],
            "name": "transfer",
            "outputs": [
    -            {
    -                "name": "",
    -                "type": "bool"
    -            }
            ],
            "payable": false,
            "stateMutability": "nonpayable",
            "type": "function"
        },
    ]