---
eip: 4521
title: 721/20-compatible transfer
description: Recommends a simple extension to make NFTs compatible with apps and contracts that handle fungibles.
author: Ross Campbell (@z0r0z)
discussions-to: https://ethereum-magicians.org/t/eip-4521-721-20-compatible-transfer/7903
status: Stagnant
type: Standards Track
category: ERC
created: 2021-12-13
requires: 721
---

## Abstract
ERC-721, the popular standard for non-fungible tokens (NFTs), includes send functions, such as `transferFrom()` and `safeTransferFrom()`, but does not include a backwards-compatible `transfer()` found in fungible ERC-20 tokens. This standard provides references to add such a `transfer()`.

## Motivation
This standard proposes a simple extension to allow NFTs to work with contracts designed to manage ERC-20s and many consumer wallets which expect to be able to execute a token `transfer()`. For example, if an NFT is inadvertently sent to a contract that typically handles ERC-20, that NFT will be locked. It should also simplify the task for contract programmers if they can rely on `transfer()` to both handle ERC-20 and NFTs.

## Specification
The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119.

The interface for ERC-4521 `transfer()` MUST conform to ERC-20 and resulting transfers MUST fire the `Transfer` event as described in ERC-721.

```sol
function transfer(address to, uint256 tokenId) external returns (bool success);
```

## Rationale
Replicating ERC-20 `transfer()` with just a minor change to accurately reflect that a unique `tokenId` rather than fungible sum is being sent is desirable for code simplicity and to make integration easier.

## Backwards Compatibility
This EIP does not introduce any known backward compatibility issues.

## Reference Implementation
A reference implementation of an ERC-4521 `transfer()`:

```sol
function transfer(address to, uint256 tokenId) public virtual returns (bool success) {
        require(msg.sender == ownerOf[tokenId], "NOT_OWNER");

        unchecked {
            balanceOf[msg.sender]--; 
        
            balanceOf[to]++;
        }
        
        delete getApproved[tokenId];
        
        ownerOf[tokenId] = to;
        
        emit Transfer(msg.sender, to, tokenId); 
        
        success = true;
}
```

## Security Considerations
Implementers must be sure to include the relevant return `bool` value for an ERC-4521 in order to conform with existing contracts that use ERC-20 interfaces, otherwise, NFTs may be locked unless a `safeTransfer` is used in such contracts.

## Copyright
Copyright and related rights waived via [CC0](../LICENSE.md).
