I'd like to be able to create a pool where users can deposit and withdraw ERC20 tokens. The caveat is that I don't have access to the assets in the pool but can only approve/reject the withdraw requests of the users.

  • User creates a withdraw of 100 USDT
  • I will approve the amount
  • contract deducts the 100 USDT from it's own address and transfers that 100 to user's address.

It's possible to do it securely with ETH but I can't seem to figure out how to do it with ERC20 tokens without giving myself complete access to the assets in the pool. Is it even possible?

the code for native transfer is here:


linking to the function that needs to be changed.

1 Answer 1


Yes, I think it's possible.

  • You can store deposited values in a mapping like

     mapping(address => uint)
  • Withdraw requests also can be deposited in a mapping like this with a bool default value false

     mapping(address => mapping(value, bool)
  • Only the contract owner/manager address is allowed to change that bool value. When it's set to true, the requested erc20 token amount is transferred to the address that deposited it. And the amount is deducted from the deposit value.

With this implemantation, you will also have a history of all withdrawals in a mapping style.

And, there should be the main difference while working with ERC20 instead of ETH, the user needs to approve the contract for the erc20 token.

Edit after comments: While sending erc20 tokens from the contract to another address you should use transfer function instead of transferfrom so you don't need any approve for that. You can use transfer because your contract is calling the token contract and msg.sender value while token contract code running is equal to your contract's address.

  • my main issue is that I don't know how to set a contract's permission to erc20 token without giving myself permission to the contract's pool as well.
    – zcaudate
    Oct 8, 2022 at 13:17
  • 1
    I see, you don't need permission to send from contract address. Use "transfer" function instead of transferfrom. Because the sender will be the contract not your address. Example: ERC20.transfer(withdrawAdress, withdrawAmount); If you can add your actual code to the question, I can help more.
    – Yetik
    Oct 8, 2022 at 13:46
  • I've added a link to the native contract code.. why is the sender the contract address? I thought that msg.sender was always the address of the user that called the contract.
    – zcaudate
    Oct 9, 2022 at 17:52
  • While your contract is working, msg.sender is the address of the user that called the contract. But when working with ERC20 tokens, you are calling token's contract from your contract. While the code in token's contract running msg.sender will be the contract's address because your contract is the caller. So, if you want to move ERC20 funds stored in a contract address, you can simply call the transfer function of the erc20 token and you don't need any allowance. You only need allowance if you are moving funds that belongs to other addresses. (transferfrom)
    – Yetik
    Oct 9, 2022 at 18:17
  • 1
    oh. that makes a lot of sense. I'll give it a go. Thanks for your help!
    – zcaudate
    Oct 10, 2022 at 0:47

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.