I'm trying to develop a contract to which users would send certain amounts of tokens A and B to the smart contract. Easiest/obvious way to do it would be to do several transactions in this order:

  1. User calls approve for tokenA for an amount of X where the smart contract is the spender
  2. User calls approve for tokenB for an amount of Y where the smart contract is the spender
  3. User then calls the smart contract which uses transferFrom the user to the smart contract for those amounts

This is however very cumbersome for the user, who has to sign and send 3 different transactions.

Is there a way where the user can call a single function in my smart contract, and the smart contract can transfer those funds from the user directly? I'm thinking something similar to what Uniswap v2 uses:

// bytes4(keccak256(bytes('transfer(address,uint256)')));
(bool success, bytes memory data) = token.call(abi.encodeWithSelector(0xa9059cbb, to, value));

Although probably using delegatecall() would be more appropiate in this context.

Would this work or would the user still need to set an approval? Any ideas on how could I improve the user experience in this case?

1 Answer 1


Unfortunately no, and that is by design. A smart contract that just needs one call to approve all your erc20 to be transferred to someone else is obviously a huge security issue.

If you want to approve a token, you need to call the approve function of that token. No way around it.

  • Thanks for your answer. And why wouldn't it work to call (bool success, bytes memory data) = token.delegatecall(abi.encodeWithSelector(0xa9059cbb, to, value)); ? Wouldn't even be like if the EOA calling the smart contract function is also directly calling the transfer() function of the token directly (since we are using delegatecall() ?
    – Hiperfly
    Commented Nov 21, 2022 at 3:16
  • I'm sorry, I'm not sure I understood your second question. Could you explain? Also, could you mark my answer as valid if it helped you? Thanks Commented Nov 21, 2022 at 6:14
  • Because of the context, if we use delegatecall() it would be as if the EOA account is calling transfer themselves even if there is a smart contract in the middle calling the transfer function for them. Sorry I'm afraid I can't marked as valid since I think this proposal would be valid but the answer doesn't addresses if that is actually correct or not.
    – Hiperfly
    Commented Nov 21, 2022 at 7:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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