0

I want to build a dispatcher contract that acts as follows: I you transfer ERC20 tokens to it, the contracts forwards them to another address. To accomplish this, I'm mainly trying to wrap my head around two things:

  • Which method can I use to "wake up" the contract when it receives ERC20 tokens? I guess the built-in method receive() will only be triggered if the contract receives native tokens?
  • I know I can transfer ERC20 tokens if I know the address of the token, but I want my contract to be able to handle all ERC20 tokens. Can I somehow get the contract of the ERC20 token it's receiving?

1 Answer 1

1

For a contract to be able to handle all ERC20 tokens use a library like openzeppelins SafeERC20. NOTE that allowing every ERC20 contract to be used in your contract can introduce different kinds of security risks and unexpected behaviour to your functions, depending on how the ERC20 contract is written.

Not sure for what purposes you want but you could write a simple withdraw function to remove "stuck" tokens from the contract.


import "node_modules/@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";

contract Something{

    using SafeERC20 for IERC20;

    address owner;

    constructor(){
        owner = msg.sender;
    }

    function withdraw(address _token) public {

        uint amount = IERC20(_token).balanceOf(address(this));
    
        IERC20(_token).safeTransfer(owner, amount);
    }
}

This way anyone can send any ERC20 tokens to your contract and you (or anyone you decide to) can remove these tokens and send them to another contract, or use them in some functions, etc. (NOTE: again, that if you're going to use any token, you should include a function to approve tokens and add them to a mapping mapping(address=>bool) isApproved; and include check in those functions require(isApproved[_token]);

To "wake up" a contract, not 100 sure how you mean, but either do it offchain by having a program checking the incoming transactions, or by having a deposit function that other contracts and users use to send erc20 tokens to it (not sure why anyone would want to send tokens randomly to a contract anyway so)

function deposit(address _token, uint _amount) public {
    
   IERC20(_token).safeTransferFrom(msg.sender,address(this),_amount);
   
   // emit an event that you can easily watch for offchain
   emit TokenRecieved(_token, _amount, msg.sender);
   // maybe add some data struct if you want to use information within contract
   Deposit storage deposit = deposits[id];
   deposit.amount = amount;
   deposit.token = token;
   
   id++;
}

NOTE: Code not tested, it's just to give you some ideas.

7
  • Thanks for your reply! The SafeERC20 library was exactly what I was looking for, I don't need support for all tokens, just the most common ones. As for "waking up" the contract: a custom deposit method is not going to work unfortunately, because the sender will not know of this method. Consider the following use case: the contract collects royalties from NFT sales, and dispatches them to other addresses. On marketplaces like opensea, you can only enter one beneficiary address. Opensea just sends the royalties, unaware of any custom methods. So I basically need a method that auto-triggers.
    – binoculars
    Apr 4 at 11:28
  • Maybe I can use fallback() for this, instead of receive()?
    – binoculars
    Apr 4 at 11:32
  • I was looking at the SafeERC20 utility, turn out I misinterpreted your answer I think. At least I still don't know how to detect which token is being sent to the contract.
    – binoculars
    Apr 4 at 11:41
  • 1
    if the royalties are in ETH then you could build something using those functions. Otherwise I think you'll have to watch for incoming transactions offchain and then trigger a withdraw/send function in your contract on an ERC20 transfer to your contract. There might be a way to make something using inline assembly and YUL, that will however get complicated. Apr 4 at 11:43
  • Got it, thanks!
    – binoculars
    Apr 4 at 11:51

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.