I'm trying to buy some CHY with USDT on Uniswap main net, fails with error 'TransferHelper: TRANSFER_FROM_FAILED'
,
This is my failed tx link.
This is a successful tx link from someone else.
I notice my transaction fee is abnormally high, much higher than other successful txs, and no matter how I raise the gasLimit
, it always used up, only takes more time.
On the page of successful tx there is Uniswap V2: CHY-USDT, which is not used in my code, is this the reason that my tx never find a correct way, but always keep finding and eat up all the gas?
How to correct the code?
Update 1: add "approve()" before transacting. The "approve()" succeeded the first time, after that it never succeeded again, always fails like this
const CHY = new Token(ChainId.MAINNET, '0x35A23BC27c345b36DeE700a256F69C6334030971', 9)
const USDT = new Token(ChainId.MAINNET, '0xdAC17F958D2ee523a2206206994597C13D831ec7', 6)
const pair = await Fetcher.fetchPairData(CHY, USDT)
const route = new Route([pair], USDT) // direction, from USDT -> CHY
var base = ethers.BigNumber.from(10).pow(route.path[0].decimals)
var amountIn = ethers.BigNumber.from(50).mul(base) // 50 * 10^6 == 50 USDT
console.log(amountIn.toString()) // 50 USDT
const trade = new Trade(
route,
new TokenAmount(USDT, amountIn),
TradeType.EXACT_INPUT)
const slippageTolerance = new Percent('50', '10000') // 0.5%
const amountOutMin = trade.minimumAmountOut(slippageTolerance).raw
const path = [USDT.address, CHY.address] // <---------check direction
const to = MY_WALLET;
const deadline = Math.floor(Date.now() / 1000) + 20*60 // 20 minutes
const provider = ethers.getDefaultProvider('mainnet', {
infura: INFURA_ID
})
const signer = new ethers.Wallet(MY_WALLET_PRIVATE_KEY)
const account = signer.connect(provider)
const uniswap = new ethers.Contract(
'0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D', // fixed Route02.addr
['function swapExactTokensForTokens( uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline) external returns (uint[] memory amounts)'],
account
)
// approve
const contract_usdt = new ethers.Contract(
addr_usdt,
//['function approve(address spender, uint value) public'],
['function approve(address spender, uint amount) public returns(bool)'],
account
);
const tx_approve = await contract_usdt.approve(uniswap.address, amountIn, {
gasPrice: gasPrice,
gasLimit: gasLimit
})
console.log('tx_approve: ' + tx_approve.hash);
const receipt_approve = await tx_approve.wait()
console.log(receipt_approve)
const tx = await uniswap.swapExactTokensForTokens(
amountIn.toString(),
amountOutMin.toString(),
path,
to,
deadline,
{
gasLimit: 400000,
gasPrice: ethers.utils.parseUnits("40", "gwei")
}
)
console.log(`Transaction hash: ${tx.hash}`)
const receipt = await tx.wait()
And I tried path=[USDT, UNIWAP_V2_CHY_USDT, CHY]
, also fails