7

In our dapp, we currently have the following user flow:

  1. Approve the Sablier contract to spend up to x ERC20 tokens
  2. Transfer the x ERC20 tokens to the Sablier contract

This is not super bad UX, but it would certainly be nicer if users signed only one transaction.

I'm aware of the "enable max" strategy, where you ask the user to approve the token with a stupendously high value, but I don't find it safe.

Is there a way in which we could have our cake and eat it too? That is, do both the approval and the transfer in one transaction? Maybe with CREATE2?

  • 1
    Well, if you use a contract as wallet you can program it to execute approve+transferFrom in a single transaction. There's an article about from ricmoo about using create2 blog.ricmoo.com/wisps-the-magical-world-of-create2-5c2177027604 – Ismael Feb 6 at 4:55
  • Thanks @Ismael but this seems to be a like a solution specific to smart contract wallets like Argent. There is no general-purpose solution, is there? – Paul Razvan Berg Feb 6 at 10:51
  • 1
    I'm not aware of something more general, but I won't say that it impossible to do. For me ERC-20 is the limiting factor here, perhaps a better standard EIP-777 are the way to go. – Ismael Feb 6 at 14:08
  • I'm not sure if I understand the question correctly and I don't quite understand the business case: what is the system used for? Is your problem that a contract can't detect when it receives tokens and that's why a second transaction is needed to tell it that? – Lauri Peltonen Feb 13 at 6:00
  • 1
    @LauriPeltonen we'd like to be able to ask users to sign only 1 transaction instead of 2. See this issue to read more about user flow and understand why signing two transactions is a brittle set up. – Paul Razvan Berg Feb 13 at 11:24
3

it is possible to batch approve+transfer in one atomic call transaction using Create2 opcode

check this link for more information https://medium.com/coinmonks/on-efficient-ethereum-transactions-introducing-homework-6ae4f21801ed

You can have user create a transaction which deploys transaction contract as explained in above article and then self destruct it after execution taking over the gas refund on self destruct

still this operation is not good with respect to gas cost associated for such operation according to me

Homework Github has a usage guide https://github.com/0age/HomeWork#usage

Note:HomeWork code is highly experimental and still in development phase,using it in production is risk

You can join HomeWork discord if you have any questions https://discord.gg/qqmKtNm

| improve this answer | |
  • Can you share more details on "this operation is not good with respect to gas"? Some numbers? – Paul Razvan Berg Feb 17 at 12:56
3

This particular behaviour can be seen throughout most Dapps which interact with a users token balance in some way or another. Uniswap, 1inch, Bancor and many more of the leading Dapps require the user to approve the token transfer in a seperate transaction before the actual transfer of tokens can be executed.

The reason why this is necessary is due to the design of ERC-20 tokens. When a contract receives ETH the sender of that transaction is available to the contract. This is not possible with ERC20 tokens however - the receiving contract has to transfer the tokens on behalf of the user to be able to know where it received the tokens from. Obviously, the user has to give authorization to the receiving contract to move his/her tokens first.

As you wrote in your question, there is the possibility to allow the receiving contract unlimited access to the users funds. This way only one authorization transaction is neccessary per user and per token. At the moment this is unfortunately the best general solution to the problem we have in regards to creating as few transactions for the end-user as possible and is supported by most Dapps. From a security point of view, this is not a good solution though.

In the original CREATE opcode the address for a contract is a function of the deployers account and nonce and thus not accurately predictable. The CREATE2 instruction was later added through EIP-1014 and changes the way contracts are deployed. CREATE2 makes it possible to calculate the addresses of contracts deployed in the future. This allows to "interact" with contracts which are not deployed yet. However, CREATE2 does not really help to solve the problem from your question.

| improve this answer | |
  • Giving unlimited access to one token's balance is NOT "the best general solution". I gave a talk at Devcon4 about why this is an insecure implementation. – Paul Razvan Berg Feb 17 at 12:55
  • I agree with it being insecure. What I meant by my statement is that it is the best general solution in regards of creating as few transactions for the end-user as possible. – thesys Feb 17 at 15:05
  • I edited / extended my answer to make that clear. – thesys Feb 17 at 15:06
  • Sorry, I know I should not be using comments this way. I gave the other three answerers 5 DAI for taking the time to answer this question, but I could not figure out who you are @thesys If you could let me know your Gitcoin profiles URL, I can send you a 5 DAI tip. – Walid Mujahid وليد مجاهد Mar 2 at 21:51
  • That's very nice! My profile is: gitcoin.co/bobface – thesys Mar 2 at 22:32
0

Seems it is not possible even with Create2 Unless there is a function in the contract

I would check to see if the third party token has implemented any mechanism for approve and call that you can use.

Otherwise you are asking users to approve (ideally to cover multiple actions on your contract) and then call in two separate transactions.

According to the OpenZepplein team you need to explain the UX in a better way than handle it on the smart contract side!

Read More about it here

| improve this answer | |
0

You need to partner with a wallet which auto approve transactions after 1 time setup.. metamask can build that feature , like if in settings if i have whitelisted a contract or application(sablier here) and have chose a limit(say 1 eth) . so for any sablier transaction less than 1 eth will approve and transfer in just one single transaction.

or either you can have this one time setup in your application yourself by making such contracts which hold user funds,which can allow all those who signed up for the setup won't have to approve multiple transactions

With an EIP an special erc token can be created just for this purpose which can be streamed and transferred easily with near zero gas costs .

| improve this answer | |
  • You don't have to partner with a wallet to check the current approval limit. We're doing this already and show the first transaction is the approval is enough. The question was really about whether there is any way to batch these. – Paul Razvan Berg Feb 19 at 16:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.