[Bug]: Stuck pending transactions
Describe the bug
When integrating the MM SDK into the portfolio dapp we bumped into an issue where one transaction would get stuck even though the app reported to be submitted to the mempool.
Important details about the issue:
- Every transaction after the transaction that "stalled" gets stuck in that same "stalled" state.
- Trying to cancel the transaction via MM Mobile would not take any effect
- Closing and opening the wallet would not allow us to move forward
- Only uninstalling and installing the app again would clean this state
- To effectively cancel this transaction we would have to manually hardcode the
noncetogetTransactionCount - 1 - Bumping both gas and gasPrice (separately or together) would not make it go through
- We never manged to reproduce this in any other chain different than Polygon mainnet
Expected behavior
The wallet is able to recover
Screenshots/Recordings
https://github.com/MetaMask/metamask-mobile/assets/104831203/35649a88-b50b-4fd4-942a-60277a73fd27
Steps to reproduce
Even though reproducing this issue in a consistent way is very hard, the times we managed to do it were by creating a transaction with the following payload:
chainId: 137
data: "0x5f57552900000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000136f6e65496e6368563546656544796e616d69630000000000000000000000000000000000000000000000000000000000000000000000000000000000000004c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003c499c542cef5e3811e1192ce70d8cc03d5c33590000000000000000000000000000000000000000000000000023375dc1560800000000000000000000000000000000000000000000000000000000000000196e000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000004f94ae6af800000000000000000000000000930dedddb92fef1b4ab2665d250877339f064eac0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000038862e238bb00000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000002e0000000000000000000000000000000000000000000000000000000000000036000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000023375dc1560800800000000000000000000000000000000000000000000000000000000000196e000000000000000000000000000000000000000000000000000000e3807ae37f0000000000000000000000003c499c542cef5e3811e1192ce70d8cc03d5c33590000000000000000000000000d500b1d8e8ef31e21c99d1db9a6444d3adf1270000000000000000000000000b41815a9803487d5bf51a549f842cb86f64836d900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003bec6f2800000000000000000000000000000000000000000000005150ae84a8cdf00000000000a4000000a4000000a4000000a400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000a4bf15fcd8000000000000000000000000a5eb255ef45dfb48b5d133d08833def69871691d000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000242cc2878d0065ba412300000000000000b41815a9803487d5bf51a549f842cb86f64836d90000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004106ab28976895bae49fb6be39a62ca34477f22b0c4a07d6ee38bc5e50c57599dc633867aba5f2193e795420fd3ec0f5ebdeb2dba303a13f8b88603fdea3ae70f61b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ab4991fe00000000000000000000000000000000000000000000000000d3"
from: "0x7a1d598f56ebcff8578170d902aca24c0d8c7ca6"
to: "0x1a1ec25DC08e98e5E93F1104B5e5cdD298707d31"
value: "0x2386f26fc10000"
Error messages or log output
No response
Version
7.15.0
Build type
None
Device
All
Operating system
iOS, Android
Additional context
No response
Severity
No response
Notes from discussion with @christopherferreira9 and @sleepytanya:
[!NOTE] Infura was having network issues with Polygon at the time the bug was reproduced (source?).
However, even if the bug was triggered by a network issue, the wallet should still be able to recover.
Notes on Reproducibility
- Reproducible for 6 attempts and then could not be reproduced for hours.
- "Very hard" to reproduce
- Testing was done on a real device.
- only the payload seems to matter, not the dapp. In this case it was a contract call for swaps.
- The amount does not seem to be relevant
- tried bumping gas, gas price to no avail
Steps to reproduce
- Visit test dapp that @christopherferreira9 set up: https://mmsdk-polygon-swap.vercel.app/
- confirm the transaction in metamask
- When bug is triggered, you see the transaction submitted but it seems like no one picks up the transaction.
Observation: Nonce value seems related
- original stuck transaction get nonce of getTransactionCount + 1
- trying to cancel to same nonce did not work
- cancelling with getTransactionCount (instead of getTransactionCount + 1) cleared the pending transaction!
Notes to inform Severity
- The bug is likely present in production. No information on whether it is and if so, how long it has been.
- Blocks user from making further transaction
- Only re-installing the app cleared up the stuck transactions. Restarting the app did not work.
- No funds are lost. No harm to user: transactions simply fail.
Thanks to @sleepytanya for the state logs:
In between the two reproductions, tanya uninstalled and re-installed the metamask app.
Testing on the extension 11.11.0, Chrome, https://mmsdk-polygon-swap.vercel.app/. https://polygonscan.com/address/0x2990079bcdEe240329a520d2444386FC119da21a Logs Firefox, tx 797 and 798: MetaMask state logs_huddle.json Logs Chrome: MetaMask state logs123.json
-
Txs with nonces 797 and 798 were made on Firefox, both were stuck.
-
I switched to Chrome about 2 hours later, installed extension and tried to perform a swap. Wallet suggested the nonce that was already used on Firefox - 797.
-
Sending two transactions (797 and 798) that were already stuck on Firefox two hours earlier resulted in failed transactions (I also tried to send 796 tx which also failed): https://recordit.co/iMlE9XeSGx
-
Sending transaction nonce 799, trying to speed up the tx (unsuccessfully): https://recordit.co/rCIGPsn1S6
-
Tx 799 stays pending for about 20 mins, after I cancel it and Polygonscan is not detecting it anymore. In the Activity tab tx 799 status switches to 'Signed' -> 'Dropped'.
-
Cancelled 799 tx can be seen on Polygonscan after ~5 mins it was displayed as 'dropped' in the UI.
-
Sending tx nonce 800, stuck, reflected on Polygonscan as 'pending'. Clicking on 'cancel, then 'speed up this cancellation' changes tx status to 'signed' and then to ' pending' again. Tx can't be found on Polygonscan: https://recordit.co/wS3tSnQZme
-
After about 20 mins tx 800 is displayed as 'dropped' in the Activity tab. On Polygon it's shown as 'fail' - reverted / cancelled transaction:
-
Cancelling stuck tx with tx with same nonce doesn't work (it results in 'failed' tx)
-
Using nonce +1 doesn't do anything with the stuck transaction, +1 tx also stays stuck.
-
Stuck txs stay in 'pending' state as long as 3 hours or may be longer (I cancelled them after 3 hours). Cancelling seems to work, very slow, but randomly it results in 'reverted' transaction with Polygonscan showing assets transferred (like tx 800).
-
Here I have two stuck transactions nonces 807 and 808, after cancelling they switched to 'signed' state and stayed in this state for about 20 mins. I tried to send another tx (nonce 809) while still having 807 and 808 txs in 'signed' state and was unable to do it. Error message on Confirmation screen 'A previous transaction is still being signed or submitted' and 'Confirm' button is not available: https://recordit.co/9PwE0YNDX5 Txs 807 and 808 displayed as 'signed' in the Activity tab, Polygonscan showing them as 'confirmed' 51 mins ago: https://recordit.co/QjfmwtH6RO
Address 0x2990079bcdee240329a520d2444386fc119da21a Net result of both tests: no new transactions on polygonscan.
Test_A - local iOS simulator on main branch
TLDR; Reproduced limbo tx; able to cancel
- Nonce 808: (Previous) Last successful transaction
- Nonce 809: (Previous) Failed execution reverted
- Nonce 810: Swap transaction – does not appear on Polygonscan
- Nonce 810 Cancelled successfully
- Nonce 810: Swap transaction – does not appear on Polygonscan - second attempt
- Nonce 810 Cancelled successfully after a few “Transaction Failed” errors
Test_B - real iPhone v7.15.0 (1245)
TLDR; Reproduce limbo tx; errors prevent cancel; ⚠️ tx is confirmed... in limbo Test B state-logs-v7.15.0-(1245).json
- Nonce 808: (Previous) Last successful transaction
- Nonce 809: (Previous) Failed execution reverted
- Nonce 810: Swap transaction – does not appear on Polygonscan
- Tried cancelling nine times but got “Transaction Failed” each time
- Nonce 810: ⚠️ 30 minutes later showing as "confirmed" in the wallet activity. Still not appearing on Polygonscan.
Fixed by https://github.com/MetaMask/metamask-mobile/pull/8707. Now when we send a transaction from the vercel test dapp we do see it on polygonscan. E.g.: https://polygonscan.com/tx/0x2282936ddf1eb016ec7b29b71c58934a1050404dbe60c2c200767dbffdb1f032