Is it possible to forbid to a smart-contract to receive all erc20 tokens and ether except my own token that was created in another contract? I mean I want my contract to receive only tokens from previously known address of smart-contract. I tried to compare token.balanceOf(msg.sender) >= msg.value where ERC20Detailed token = ERC20Detailed(_address); but as I understood when you send tokens msg.value is always 0

3 Answers 3


Transferring tokens is basically to change the entries in a variable in the token contract. This means that there is nothing actually moved.

Assume a user with address A, a token contract B and another contract (yours) with address C.

If A decides to sent x tokens to your contract C what happens is that a transaction is sent to B. B has a mapping with the balances of all the users, and subtract x tokens from the balance of A and adds x tokens to the balance of C. This means that C never get to know that a transfer of x tokens was sent to it.

This is why you can't forbid tokens to be sent to your contract because transferring tokens to your contract do not involve your contract at all.

However, there is an option. ERC20 standard implements a function approveAndCall which allows users (for instance A) to approve your contract (C) to move x amount of tokens from their balance in (B). This function will actually call your contract and you will see the address of the token. If the call is from your token contract you can just transfer from the x tokens to you contract using transferFrom and execute your code. If the call is from another contract you just revert.

For the rest, if someone does normal transactions to your contract, you do not need to worry, your contract will will never know.

Hope this helps.


There is no way to prevent your contract from receiving tokens. This is mostly due to the fact that the contract doesn't explicitly "receive" them in any way but the address is simply marked as a token holder in the token contract.

Due to partially the same reasons it is also not possible to monitor token "receivals" in a smart contract so you can't trigger something when your contract receives tokens.

You can mostly prevent your contract from receiving Ether but there are a few exceptions: https://ethereum.stackexchange.com/a/63195/31933 . Otherwise, if your contract doesn't have a payable function, it cannot receive Ethers.

  • Thanks for your answer! And it's impossible to check what token was sent and call revert() if needed? Is there any way to get contract address of token that was sent?
    – Aleksandr
    Mar 11, 2019 at 10:07
  • Edited my answer to add info about monitoring token receivals (it's not possible). You can only track them off-blockchain with something like etherscan.io Mar 11, 2019 at 11:07

Actually point made by Jaime is right. You cannot really stop your contract from receiving tokens, however, you can use approveAndCall to receive tokens on the front end of your dapp. And yes there is a way to verify if the sending address is a contract address and also if it is your own contract, hence revert. Check out ERC223 standard, lots were discussed there.


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.