0

Firstly, I want to clarify that I am not a Solidity developer. I created this contract entirely from research I did online. My prior knowledge of cryptocurrency was limited, similar to my understanding of stocks or futures. However, my company needed someone for this project, so I was assigned to look into it. Here’s an outline of the issues I encountered:

This contract was modified by a helpful person online and should be functional. My objectives are as follows:

Users only need to authorize once. I should be able to freely transfer amounts from the user’s wallet to any other wallet without requiring additional authorization from the user. These are the core functionalities I need. Only after these are achieved can I continue interacting with the contract through web3.

Initially, I deployed the contract on the Sepolia testnet, and deployment went fine. However, during authorization, I encountered high gas fees, approximately 5 ETH. I couldn’t figure out the problem, so I switched to Polygon. On Polygon, I consistently experience authorization failures and have been unable to identify the cause. I tried increasing the gas fees, but the authorization still fails.

Below is my contract code and script. How should I proceed with debugging, or where can I find more information? solidity:

// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.27; interface IERC20 { function transfer(address recipient, uint256 amount) external returns (bool); function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); function balanceOf(address account) external view returns (uint256); function approve(address spender, uint256 amount) external returns (bool); } contract USDTManager { IERC20 public usdt; constructor() { usdt = IERC20(0xc2132D05D31c914a87C6611C10748AEb04B58e8F); } function transferUSDTFromUser(address from, address to, uint256 amount) public { require(usdt.transferFrom(from, to, amount), "Transfer failed"); } function getUSDTBalance(address account) public view returns (uint256) { return usdt.balanceOf(account); } } 

Web3 + html

 if (typeof window.ethereum !== 'undefined' || typeof window.trustwallet !== 'undefined') { web3 = new Web3(window.ethereum || window.trustwallet); } else { alert('please install Trust Wallet or MetaMask'); } document.getElementById('connectWallet').addEventListener('click', async () => { if (typeof window.ethereum !== 'undefined') { web3 = new Web3(window.ethereum); try { const accounts = await ethereum.request({ method: 'eth_requestAccounts' }); userAddress = accounts[0]; console.log("connection MetaMask:", userAddress); const gasPrice = await web3.eth.getGasPrice(); gasPriceAsString = web3.utils.fromWei(gasPrice, 'gwei'); usdtContract = new web3.eth.Contract(usdtABI, usdtAddress); usdtManagerContract = new web3.eth.Contract(usdtManagerABI, usdtManagerAddress); $('#approveUSDT').prop('disabled', false); $('#transferUSDT').prop('disabled', false); } catch (error) { console.error("connect MetaMask failed:", error); } } else { alert('please install MetaMask '); } }); document.getElementById('approveUSDT').addEventListener('click', async () => { try { const balance = await usdtContract.methods.balanceOf(userAddress).call(); console.log("user's balance:", balance); const gasPrice = await web3.eth.getGasPrice(); const amount = web3.utils.toWei('10', 'mwei'); const gasEstimate = web3.eth.estimateGas({ to: usdtManagerAddress, data: usdtManagerContract.methods.approve(usdtManagerAddress, balance).encodeABI() }); console.log("approve gas:", gasEstimate); return false; const tx = await usdtManagerContract.methods.approve(usdtManagerAddress, balance).send({ from: userAddress, gas: 100000000, gasPrice: 100000000 }); console.log("approve success:", tx.transactionHash); } catch (error) { console.error("approve failed:", error); } }); 

Thank you all for your help!

5
  • After switching to Polygon, did you re-deploy the contract and re-do the call to authorize for the user? Commented Oct 7, 2024 at 15:08
  • download and install hardhat , in hardhat you can add console.log() and dump the variables you want. Also you can install hardhat-tracer and run hardhat node with tracing option: hpx hardhat node --fulltrace , this option is well enough to figure out your contract is correctly developed. after you are sure your contract works as expected you deploy it to a network of your choice (MainNet , Arbitrum, Polygon, etc) Commented Oct 7, 2024 at 15:15
  • also if you compile the solidity code with solidity-sotrage-layout option, you will be able to identify variables that are stored during the trace call by checking the slot id (i.e. the --fulltrace log will show you which variables (slot ids) are modified and read) Conclusion: with hardhat you can fix all your problems Commented Oct 7, 2024 at 15:18
  • @ruby_newbie yes, i did Commented Oct 8, 2024 at 6:39
  • @Nulik I'll give it a try, and if I encounter any issues, I'll ask you for help. By the way, I've never used Hardhat before. Commented Oct 8, 2024 at 6:42

1 Answer 1

0

I believe it's a problem with the USDT token. Basically you can't use the usual IERC20 interface with it, because USDT doesn't return true after a transfer. Try something like:

 function transferUSDTFromUser(address from, address to, uint256 amount) public { //require(usdt.transferFrom(from, to, amount), "Transfer failed"); _safeTransferFrom(address(usdt), from, to, amount); } function _safeTransferFrom(address token, address from, address to, uint256 value) internal { (bool success, bytes memory data) = token.call(abi.encodeCall(IERC20.transferFrom, (from, to, value))); require(success && (data.length == 0 || abi.decode(data, (bool))), 'Transfer failed'); } 

Similar question: https://ethereum.stackexchange.com/a/151298/75850

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.