0

I am now developing a ICO smart contract which receives USDT tokens from other people and withdraw.

My withdraw function in contract is below.

function withdraw() external onlyOwner onlyContractHasMoney {
        // here, contract will send usdt to _wallet
        uint balance = _usdtToken.balanceOf(address(this));
        _usdtToken.transfer(_wallet, balance);
}

And here is USDT transfer code that I wrote for localhost test purpose.

function transfer(address _to, uint _value) public onlyPayloadSize(2 * 32) {
        console.log("msg sender of transfering is %s", msg.sender);
        uint fee = (_value.mul(basisPointsRate)).div(10000);
        if (fee > maximumFee) {
            fee = maximumFee;
        }
        uint sendAmount = _value.sub(fee);
        console.log("balance of msg sendger is %s and transfering value is %s, receiving address is %s", balances[msg.sender], _value, _to);
        balances[msg.sender] = balances[msg.sender].sub(_value);
        balances[_to] = balances[_to].add(sendAmount);
        if (fee > 0) {
            balances[owner] = balances[owner].add(fee);
            Transfer(msg.sender, owner, fee);
        }
        Transfer(msg.sender, _to, sendAmount);
        console.log("there is no problem until yet");
}

And my javascript withdraw scripts is below.

const hre = require("hardhat");
const ICO = require('../../clients/artifacts/contracts/ico.json');

async function main() {
    const icoAddress = ICO.address;
    const icoABI = ICO.abi;

    const [signer] = await ethers.getSigners();

    const ico = new hre.ethers.Contract(icoAddress, icoABI, signer);

    await ico.withdraw();
}

main()
  .then(() => process.exit(0))
  .catch((error) => {
    console.error(error);
    process.exit(1);
  });

But when I run the script, I am getting this error.

enter image description here enter image description here

As you can see, USDT transfer transaction reverted because of UNPREDICTABLE_GAS_LIMIT, not usdt transfer code itself. I am not sure how can I resolve this issue. Do you have any idea to solve this problem? Please help me!

3
  • There might be an error in the addresses you're using for USDT, is the USDT contract properly added and exists on the chain where you're sending the transaction? Without more details this will be difficult to catch the error
    – Adam Boudj
    Commented Mar 25, 2023 at 9:07
  • I used Tether.sol file for USDT test purpose on localhost, so USDT address itself is correct. I even added console.log to Tether.sol file to see if I set USDT address correctly, and confirmed it's exact address. Commented Mar 25, 2023 at 10:59
  • and what about the modifier?
    – Adam Boudj
    Commented Mar 25, 2023 at 13:27

4 Answers 4

0

The error is saying that can't estimate the gas limit. Just add hardcoded one ase that:

await ico.withdraw({ gasLimit: 3000000 });
1
  • 1
    good answer, thank you! Commented Mar 28, 2023 at 0:21
0

I think the contract first has to approve the transcation, then you can call the method tranfer().

1
  • I am sorry as I didn't tell I tested on localhost with Tether.sol for usdt. I will add tether code that I wrote soon. Commented Mar 26, 2023 at 23:01
0

Without looking at the rest of the code the only thing that comes to mind is that you're using a wrong interface for _usdtToken. It's a common error since USDT doesn't conform exactly to ERC20.

Try adding this:

interface IUSDT {
    function transfer(address, uint256) external;
}

and do this:

function withdraw() external onlyOwner onlyContractHasMoney {
        // here, contract will send usdt to _wallet
        uint balance = _usdtToken.balanceOf(address(this));
        IUSDT(address(_usdtToken)).transfer(_wallet, balance);
}
1
  • I am sorry as I didn't tell I tested on localhost with Tether.sol for usdt. I will add tether code that I wrote soon. Commented Mar 26, 2023 at 23:01
0

i was also facing the problem and i came to know that some of the token's aren't fully compliant with the ERC20 standards.

i used safeERC20 to get rid of the error linking an article about detailed explanation of the error and the solution.

https://medium.com/@JohnnyTime/why-you-should-always-use-safeerc20-94f44aa852d8

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.