I'm trying to design this: user clicks the button and the button calls approve for ERC20 and call contract function that requires those ERC20s. But what happens it's that approve function succeeds, but the other contract function call errors that the user hasn't approved the tokens. Is there something I can do?
3 Answers
If i'm understanding correctly, when you click the button, metamask pops up 2 times in quick succession? Like, once to approve, and as soon as you confirmed it asks you to sign the second transaction? If so, you need to wait until you get the 1st transaction receipt before sending the 2nd transaction.
I don't think it's possible, because with first call you are asking a ERC20 contract to allow your contract to spend funds and only after successful transaction you can call TransferFrom from your contract.
I understand your dApp tries to make a transfer of an ERC20 token on behalf of the user. For this scenario, the most usual way is to make your user see the metamask's popup and click on it twice. Meaning, you would likely have two buttons on the page, one for the approve
method, and another one for the transferFrom
method.
Another possible way is to have your system make the second call instead of the user. This option relieves the user from having to make two clicks, however, for the transfer to be completed two transactions have to be sent to the blockchain anyway, except that you can use your own wallet for making the second one, therefore you would be able to cover the gas for the user as well as to relief them from having to make two clicks.
You must however observe that you (or your automatic script on your backend) must wait until the first transaction (the approve) is validated before trying to call transferFrom
because before then, your contract is not yet authorized to spend on behalf of the user.
You might be wondering if we could not call the whole thing by placing the whole logic for that inside on only function of your smart contract, and then have the user call that only function. Unfortunatelly that is not possible. This problem (or solution) is the main reason that brought up discussions and the creation of things like 'Gas Station' (useless on my point of view) and the EIP-4337
In brief: The quickest and most used solution is two have two buttons instead of one only.