Transfer any ERC20 token from contract

erc-20solidity

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?

Best Answer

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.

Related Topic