Failed Transactions - Review Wanted

Hi,

I just deployed my first NFT contract to Polygon Mainnet after extensive testing on Testnet and I'm now having issues with a high number of transactions failing when users try to mint an NFT. This is happening when minting from the dApp and when minting directly from the contract, so don't believe it is an issue with my dApp.

:1234: Code to reproduce

I've been looking at the errors and reviewing the contract again and the errors are related to a require statement I have in my mint function: require(msg.sender.balance >= mintCost. The mintCost is calculated using an internal function: uint256 mintCost = _calculatePrice(_mintQuantity); and the _calculatePrice function is as follows:

function _calculatePrice(uint256 numberOfTokens) 
        internal 
        view 
        returns (uint256)
        {
            return mintPrice * numberOfTokens;
        }

mintPrice is set at the top of the contract as follows: uint256 public mintPrice = 2 ether; As this is deployed on Polygon, the prices are all in MATIC.

I can't work out why this require statement is throwing up transaction errors or why it's only happening some of the time. My only guess is that it has something to do with gas prices, but can't figure out why that would be the case or if there's anything I can do to fix it.

I'd really appreciate any advice anyone can give me on this as it's really ruining the minting experience for my users and creating a lot of confusion!

The contract address is 0x0342a2d0Ed0Fb827B155404d2D1cF0aDb66F4c13 and you can see the full contract, which is verified on Polygonscan.

Thanks in advance for any help/guidance anyone can give!

I think you should change this line:

require(msg.sender.balance >= mintCost

To:

require(msg.sender.balance >= mintPrice * _mintQuantity

instead of having a function that calculates the mintCost, because I think the problem is with the return value of the _calculatePrice function

Thank you - I appreciate the reply. The issue I have is that the contract is already deployed and in use - none of these issues came up in testing or when deployed on testnet. I want to be 100% sure of what the issue is before deciding what to do as I may have to refund everyone, scrap the contract and start again, which is going to be tough!

This user had a failed tx and then sent another one and it succeeded 0x477f65bc9bd2dd33d5cf1962785064ace602b4fd

Failed tx:
0xd4ed412611b69e7bd2a58589f73b52c02295565810e64b2980bfad1253b3ff82

Successful tx:
0xc17b6a6e67c7941bd4a8ba72a20356cdb137240ed4276f117fb9960ed5205291

If you know who that is you can ask them what they did differently.

Thanks for looking at this - I have spoken to a few users and done testing myself on the deployed contract and there is no difference in what people do for successful transactions vs. ones that fail whether they're minting from the dApp or directly from the contract. That is why I think it is something like your problem with the nonReentrant modifier with payable function. There doesn't seem to be any reason why some transactions succeed and others fail.

I don't think it is the nonReenterant modifier because if that modifier is active it will not make you enter the function itself hence causing a revert before running lines. I'll try looking into your code further maybe I missed something. I know it feels awful that you are in that position. Hopefully it will get fixed.

Thank you, appreciate you taking the time to help! The issue is definitely something to do with gas - I've done some more testing and even when I try to mint for 0 MATIC the gas fees get up to 0.6 MATIC which is 100x what they normally are for a transaction. That's why I thought my issue was similar to yours as you mentioned gas increasing a huge amount for the transaction before failing.

I've been speaking to a few other people that have been experiencing similar issues with their transactions over the last few days and they have suggested that it might be a bug with metamask that is causing the gas cost to spiral and fail transactions. I've logged a support request with metamask to see if they can resolve it.

Please update me with their response once you have it. I really hope they sort it out for you!

@seanbetts PolygonScan is not showing the error messages, which must be some limitation of PolygonScan as compared to Etherscan, but if you go to this failed transaction for example, and then go to Geth Debug Trace_2:
image

There you can take the output of the reverted transaction and decode it:

0x08c379a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003a596f75722077616c6c657420646f65736e2774206861766520656e6f756768204d4154494320666f7220796f7572207472616e73616374696f6e000000000000

Most of this isn't valid ASCII/UTF-8 but the last part is the revert reason: "Your wallet doesn't have enough MATIC for your transaction" (see here).

Thank you for getting back to me - yes, that's the error message I have in the contract. My current theory is that this is a bug in MetaMask that is ballooning gas prices for the transaction and then making the transactions fail - I've logged a ticket with them but am yet to hear back.

To me this doesn't look right:

require(msg.sender.balance >= hatchPrice, "Your wallet doesn't have enough MATIC for your transaction");
require(msg.value >= hatchPrice, "You haven't sent enough MATIC in the transaction to hatch your nEGG");

Why does the contract care how much is in the sender balance?

It's just a check to ensure they have enough in their wallet to complete the transaction

The thing is if they are sending the MATIC as value attached to the transaction (i.e. msg.value) it's no longer part of their balance. So you're requiring that people have 2x the mint price, half of it to go with the transaction, the other half that should be held in their wallets.

In this tx for example the user has 12 MATIC in their account. But when they send in 10 MATIC as transaction value, msg.sender.balance will be 2.

Ah, ok - wasn't aware that balance was after the value has been removed... The balance check is before the value check so wouldn't it check the wallet before value for the transaction is removed?

I've just done some quick testing and you're absolutely right - the transaction works when I have 2x the amount needed in the wallet. That's a real pain....I'll either have to scrap the contract and start again or tell my users to have twice the Matic in their wallet for the transaction - neither is good news! Appreciate you looking at this for me - it does explain all the failed transactions! I was really hoping it wasn't a problem with the contract!

1 Like

Thankfully it's 2x MATIC and not 2x ETH :joy:

True! Still a massive PIA though....ugh