Another way to solve the two step approve and transfer process
Transfer gateways are intermediary contract that make the transfer to the destination contract before calling the contract.
They can be pre-approved globally as immutable address from the ERC20 contract (see _gateway in src/solc_0.7/Test/BaseERC20.sol) so ERC20 contract can benefit from it without requiring user confirmation.
Alternatively for existing contract, users can approve it only once and can then make purchase in any contract that support such gateways.
This technique is not exclusive to ERC20 and this repo also includes an ERC721 version.
Use case : https://mystery.market so we can deploy new sales contract without every time requiring approval for transferring ERC721 into it.
Let say there is a Sale Contract that sell some things (represented by id) for a specific price
User create the data to make the call to SaleContract
const {data, to} = await SaleContract.populateTransaction.purchase(1);
Then the User call the TransferGateway transferERC20AndCall
function with the tokeen address and amount to transfer
As shown in the diagram below, this in turn
- perforrm a transfer on the token to send the token to the destination
- call the destination and append the data, namely the sender, token address and amount to the msg.data (same as in EIP-2771)
The Gateway also allow to operate without any approval, by letting the sender make an atomic call that first transfer the token to the gateway and then call forward
as shown in the following diagram:
File | Statements | Functions | Branches | Lines | |||||
---|---|---|---|---|---|---|---|---|---|
❗ | ERC20TransferGateway.sol | 35.29% | 6/17 | 50% | 3/6 | - | - | 35.29% | 6/17 |
❗ | ERC721TransferGateway.sol | 0% | 0/13 | 0% | 0/4 | - | - | 0% | 0/13 |