---
eip: 4950
title: Entangled Tokens
description: ERC-721 extension with two tokens minted that are tied together
author: Víctor Muñoz (@victormunoz), Josep Lluis de la Rosa (@peplluis7), Easy Innova (@easyinnova)
discussions-to: https://ethereum-magicians.org/t/entangled-tokens/8702
status: Draft
type: Standards Track
category: ERC
created: 2022-03-28
requires: 20, 721, 1155
---

## Abstract

This EIP defines an interface for delegating control of a smart contract wallet to pairs of users using entangled [ERC-721](./eip-721.md) non-fungible tokens.

## Motivation

The motivation is to provide an easy way to share a wallet through NFTs, so that the act of buying an NFT (in a marketplace) gives the buyer the privilege to have access to a given wallet. This wallet could have budget in many tokens, or even be the owner of other NFTs.

A use case is to keep contact between an artist and an buyer of its NFTs. If an artist T has created a digital piece of art P with an NFT, then T creates 2 entangled tokens A and B so that he keeps A and transfer B to P. By construction of entangled tokens, only one transfer is possible for them, thus the artist proofs he’s been the creator of P by sending a transaction to A that is visible from B. Otherwise, the owner of P might check the authenticity of the artist by sending a transaction to B so that the artist might proof by showing the outcome out of A.

A version of this use case is when one user U mints his piece of art directly in the form of an entangled token A; then the user U sells/transfers it while keeping the entangled token B in the U's wallet. The piece of art and the artists will be entangled whoever is the A's owner.

These applications of entangled tokens are envisaged to be useful for:

1.	NFT authorship / art creation
2.	Distribution of royalties by the creator.
3.	Authenticity of a work of art: creation limited to the author (e.g. only 1000 copies if there are 1000 1000 entangled tokens in that NFT).
4.	Usowners (users that consume an NFT also become -partial- owners of the NFT)
5.	Reformulation of property rights: the one who owns the property receives it without having to follow in the footsteps of the owners.
6.	Identity: Only those credentials that have an entangled token with you are related to you.
7.	Vreservers (value-reservers).

## Specification

An entangled token contract implements [ERC-721](./eip-721.md) with the additional restriction that it only ever mints exactly two tokens at contract deployment: one with a `tokenId` of `0`, the other with a `tokenId` of `1`. The entangled token contract also implements a smart contract wallet that can be operated by the owners of those two tokens.

Also, a `tokenTransfer` function is to be be added in order to allow the token owners to transact with the [ERC-20](./eip-20.md) tokens owned by the contract/NFT itself. The function signature is as follows:

```solidity
    function tokenTransfer(IERC20 token, address recipient, uint256 amount) public onlyOwners;
```

## Rationale

We decide to extend [ERC-721](./eip-721.md) ([ERC-1155](./eip-1155.md) could be also possible) because the main purpose of this is to be compatible with current marketplaces platforms. This entangled NFTs will be listed in a marketplace, and the user who buys it will have then the possibility to transact with the wallet properties (fungible and non fungible tokens).

## Backwards Compatibility

No backwards compatibility issues.

## Reference Implementation

Mint two tokens, and only two, at the contract constructor, and set the `minted` property to true:

```solidity
bool private _minted;

constructor(string memory name, string memory symbol, string memory base_uri) ERC721(name, symbol) {
        baseUri = base_uri;
        _mint(msg.sender,0);
        _mint(msg.sender,1);
        _minted = true;
    }

function _mint(address to, uint256 tokenId) internal virtual override {
    require(!_minted, "ERC4950: already minted");
    super._mint(to, tokenId);
}
```

Add additional functions to allow both NFT user owners to operate with other ERC-20 tokens owned by the contract:

```solidity
    modifier onlyOwners() {
        require(balanceOf(msg.sender) > 0, "Caller does not own any of the tokens");
        _;
    }

function tokenTransfer(IERC20 token, address recipient, uint256 amount) public onlyOwners {
        token.transfer(recipient, amount);
    }
```

## Security Considerations

There are no security considerations.

## Copyright

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