I am deploying a contract today.

Tomorrow if some user mistakenly sends ETH to my contract, I can retrieve or return it if I have implemented a payable and a send function.

def __default__():
    # a basic payable to enable receiving incoming eth
    log ethReceived(msg.value, msg.sender)

def withdraw(_to: address):
    # for sending out any eth transferred in by mistake
    assert msg.sender == self.owner
    log ethSent(self.balance, msg.sender)
    send(_to, self.balance)

But what if some user mistakenly sends any other ERC-20 token or ERC-721 NFT to my contract; is there a general function I could have implemented in my contract, so I can retrieve those, as long as they follow their respective standards? I won't know the token contract in advance, it could be any valid ERC-20 or ERC-721.

Vyper code preferred, but Solidity answers or examples are also fine.


2 Answers 2


You are close with your ETH example, just need to adapt to the ERC20 standard.

# @version 0.3.2

from vyper.interfaces import ERC20

def withdraw(token: ERC20, receiver: address):
    assert msg.sender == self.owner

    balance: uint256 = token.balanceOf(self)
    log TokenSent(token, msg.sender, balance)
    token.transfer(receiver, balance)
  • Thanks! Is there any equivalent for ERC721 tokens?
    – salian.eth
    Apr 18, 2022 at 1:40
  • 1
    you would do something similar, except using the signature from the ERC721 interface - token.transferFrom(self, receiver, balance). Apr 18, 2022 at 18:23

My contract ERC20Recover does exactly what you're looking for.

If you're using an npm package manager, you can install my contracts package like this:

yarn add @prb/contracts
// or
npm install @prb/contracts

Then in your Solidity contract:

// SPDX-License-Identifier: UNLICENSED
pragma solidity >=0.8.4;

import "@prb/contracts/token/erc20/ERC20Recover.sol";

contract MyContract is ERC20Recover {
    constructor(address nonRecoverableToken) {
        // Set a list of non-recoverable tokens.
        isRecoverInitialized = true;

See how this is used in the wild here:

  • This is great, i've actually had your contract open in one tab and was seeing how this converts to vyper. Do you have any similar suggestions for ERC721?
    – salian.eth
    Apr 4, 2022 at 14:41
  • 1
    nope sorry I don't know anything about ERC721. Apr 4, 2022 at 14:42

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.