I've reviewed most all of the posts on this topic, but none of the answers are doing exactly what I need.

I have an application that allows users to submit their tokens from their contract into my "pool" at my own contract address. What I want to happen is that an outside address can request for my own contract to send them these new tokens after they pay an ETH fee. So the sequence is as follows, using random amounts for example:

  • User A (contract owner) sends 100 tokens from their contract address to my pool address (I already have this working)
  • User B (interested buyer) clicks a button on my application that will grant them 20 of these tokens from my pool address in exchange for ETH amount that is predetermined on the app.

I assume I will need to use a batch add function here to release the tokens and accept the ETH, but how do I get my pool address to approve the transaction automatically without my interference?

  • Note: My pool address can hold multiple tokens, so I would also need to specify which token is being sent during the transaction.

1 Answer 1


In step 1, the user just transfers to your contract in the ERC20 token contract. Your contract is not even aware this transfer took place.

In step 2, the user buys some token X from your contract, for a price, and your contract sends the tokens, if the contract has enough, or the transaction fails and the funds are returned to the user, which is what you want.

function(SafeERC20 token, uint amount) public payable {
  require(msg.value == amount); // price is 1:1 in the example
  // emit an event
  token.safeTransfer(msg.sender, amount);

That's about it. Use the openZeppelin SafeERC20 implementation for important protection since this lets the user pass in an untrusted contract address. Even better, whitelist token contracts so you can repel suspicious implementations and approve only well-behaved implementations.

mapping(SafeERC20 => bool) public isApproved;
require(isApproved[token], "Not an approved token.");

In the case that you reject some token contracts, you have a further concern about what to do with tokens that get marrooned in your contract, but that is a little outside the scope of the original question.

It doesn't check your contract's balance in the token of choice because the transfer will fail if your contract has insufficient funds. It the transaction fails, the ether sent will be returned to the sender. Everything in the right place. We're done.

Hope it helps.

If you


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.