ethers.js
ethers.js copied to clipboard
TX.wait() never resolves even though the transaction has already been completed.
Ethers Version
6.6.2
Search Terms
No response
Describe the Problem
TX.wait() never resolves even though the transaction has already been completed. I am using ethers.js 6.2 and hardhat to test my code. This is my code.
const routerContract = new hre.ethers.Contract(
router,
[
'function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline) external payable returns (uint[] memory amounts)'
],
signer
);
const swapTx = await routerContract.swapExactETHForTokens(
amountOutMin,
[WETH, token_address],
ME,
Date.now() + 1000 * 60 * 10,
{'value': ETHAmountIn,"gasPrice": gasPrice, "gasLimit": gasLimit}
)
//console.log(swapTx);
let receipt = await swapTx.wait();
When I run this code, the hardhat shows the transaction has already been completed. And in the wallet, I can see the swap has happed correctly.
eth_sendRawTransaction
Contract call: <UnrecognizedContract>
Transaction: 0x499d04cf2afef112c1715b7821131873a2e5475080ad20f262dda9a65b5c9864
From: 0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266
To: 0x7a250d5630b4cf539739df2c5dacb4c659f2488d
Value: 1 ETH
Gas used: 157884 of 221283
Block #17664625: 0x8d2d257060ec0bc0b0a8fbf71a1bc2cb99eaabbf6d0a2c27f8bb0b7909db99af
eth_chainId (2)
eth_getTransactionReceipt
eth_chainId
eth_subscribe
I have already tried increasing gas and tried getting the receipt through the provider like... But I am still unable to get the receipt
let reciept = await provider.waitForTransaction(swapTx.hash, 1)
I don't really know what else to do so any help would be much appreciated.
Code Snippet
No response
Contract ABI
No response
Errors
No response
Environment
node.js (v12 or newer), Hardhat
Environment (Other)
No response
I noticed a similar issue
the context is using ethers v6 in hardhat test where in most case hardhat auto-mining is enabled and where once you get a tx hash you know you can get the receipt straigthaway
with ethers v6 unfortunately it seems that the receipt cannot be fetched directly
I can workaround by changing this line: https://github.com/ethers-io/ethers.js/blob/1dd542721d3a9e74d10a92847200f4b2aa5da618/src.ts/providers/provider.ts#L1466
to always return if confirrns === 0 . this is because in some case the confirmations() return -1
I can actually make it work by using tx.wait(Number.MIN_SAFE_INTEGER) but feel like using confirmations == 0 should work here
I change my code to look like this but I still have the same problem.
let receipt = await swapTx.wait(Number.MIN_SAFE_INTEGER);
I also tried it like this
let receipt = await swapTx.wait(0);
Am I doing something wrong?
There should definitely not be any case where you have -1 confirmations. And MIN_SAFE_INTEGER really doesn’t make sense..
I have to look more into this. Can you include how you create the provider and signer?
const provider = new ethers.WebSocketProvider("ws://127.0.0.1:8545/");
const wallet = new hre.ethers.Wallet("0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"); const signer = wallet.connect(provider);
The Private key is the first wallet created by Hardhat.
@ricmoo
This appears to be caused by a race condition in the wait function.
The condition happens when the transaction is committed after the call to getTransactionReceipt https://github.com/ethers-io/ethers.js/blob/main/src.ts/providers/provider.ts#L1596 and before the call to checkReplacement https://github.com/ethers-io/ethers.js/blob/main/src.ts/providers/provider.ts#L1607
If this happens and there is no new block mined after this, then the wait will be stuck forever, as the checkReplacement will expect the transaction not to be committed up to this block.
You can likely reproduce this condition more reliably by adding a sleep for example here to allow the block to be mined with the transaction https://github.com/ethers-io/ethers.js/blob/main/src.ts/providers/provider.ts#L1608
can somebody fix this please?