Skip to content

Commit

Permalink
Merge 4b6f84f into f74302f
Browse files Browse the repository at this point in the history
  • Loading branch information
0xZeus1111 authored Jun 13, 2024
2 parents f74302f + 4b6f84f commit dc82165
Showing 1 changed file with 337 additions and 0 deletions.
337 changes: 337 additions & 0 deletions ERCS/erc-7629.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,337 @@
---
eip: 7629
title: ERC-20/ERC-721 Unified Token Interface
description: This proposal introduces a single interface for ERC-20/ERC-721 tokens, enabling seamless interaction by defining common functions for both token types.
author: 0xZeus1111 (@0xZeus1111), Nvuwa (@Nvuwa)
discussions-to: https://ethereum-magicians.org/t/erc-7629-unified-token/18793
status: Draft
type: Standards Track
category: ERC
created: 2024-02-18
requires: 20, 165, 721
---


## Abstract

This proposal introduces a protocol that establishes a unified interface for managing both [ERC-20](./eip-20.md) fungible tokens and [ERC-721](./eip-721.md) non-fungible tokens (NFTs) on the Ethereum blockchain. By defining a common set of functions applicable to both token types, developers can seamlessly interact with [ERC-20](./eip-20.md) and [ERC-721](./eip-721.md) tokens using a single interface. This simplifies integration efforts and enhances interoperability within decentralized applications (DApps).


## Motivation

The proposal aims to address the demand for assets combining the liquidity of [ERC-20](./eip-20.md) tokens and the uniqueness of [ERC-721](./eip-721.md) tokens. Current standards present a fragmentation, requiring users to choose between these features. This proposal fills that gap by providing a unified token interface, enabling smooth transitions between [ERC-20](./eip-20.md) and [ERC-721](./eip-721.md) characteristics to accommodate diverse blockchain applications.

## Specification

- Introduces a token contract that combines features from both [ERC-20](./eip-20.md) and [ERC-721](./eip-721.md) standards.
- Supports state transitions between [ERC-20](./eip-20.md) and [ERC-721](./eip-721.md) modes, facilitating seamless conversion and utilization of both liquidity and non-fungibility.
- Defines essential functions and events to support token interactions, conversions, and queries.
- Implements low gas consumption [ERC-20](./eip-20.md) mode to maintain efficiency comparable to typical [ERC-20](./eip-20.md) token transfers.


Compliant contracts MUST implement the following Solidity interface:

```solidity
pragma solidity ^0.8.0;
/**
* @title ERC-7629 Unify Token Interface
* @dev This interface defines the ERC-7629 Unify Token, which unifies ERC-721 and ERC-20 assets.
*/
interface IERC7629 is IERC165 {
// ERC-20 Transfer event
event ERC20Transfer(
address indexed from,
address indexed to,
uint256 amount
);
// ERC-721 Transfer event
event ERC721Transfer(
address indexed from,
address indexed to,
uint256 indexed tokenId
);
// ERC-721 Transfer event
event Transfer(
address indexed from,
address indexed to,
uint256 indexed tokenId
);
// Approval event for ERC-20 and ERC-721
event Approval(
address indexed owner,
address indexed approved,
uint256 indexed tokenId
);
// Approval event for ERC-20 and ERC-721
event Approval(
address indexed owner,
address indexed approved,
uint256 indexed tokenId
);
// Approval event for ERC-20
event ERC20Approval(
address indexed owner,
address indexed approved,
uint256 indexed tokenId
);
// ApprovalForAll event for ERC-721
event ApprovalForAll(
address indexed owner,
address indexed operator,
bool approved
);
// ERC-20 to ERC-721 Conversion event
event ERC20ToERC721(address indexed to, uint256 amount, uint256 tokenId);
// ERC-721 to ERC-20 Conversion event
event ERC20ToERC721(address indexed to, uint256 amount, uint256[] tokenIds);
/**
* @dev Returns the name of the token.
*/
function name() external view returns (string memory);
/**
* @dev Returns the symbol of the token.
*/
function symbol() external view returns (string memory);
/**
* @dev Returns the number of decimals used in the token.
*/
function decimals() external view returns (uint8);
/**
* @dev Returns the total supply of the ERC-20 tokens.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the balance of an address for ERC-20 tokens.
* @param owner The address to query the balance of.
*/
function balanceOf(address owner) external view returns (uint256);
/**
* @dev Returns the total supply of ERC-20 tokens.
*/
function erc20TotalSupply() external view returns (uint256);
/**
* @dev Returns the balance of an address for ERC-20 tokens.
* @param owner The address to query the balance of.
*/
function erc20BalanceOf(address owner) external view returns (uint256);
/**
* @dev Returns the total supply of ERC-721 tokens.
*/
function erc721TotalSupply() external view returns (uint256);
/**
* @dev Returns the balance of an address for ERC-721 tokens.
* @param owner The address to query the balance of.
*/
function erc721BalanceOf(address owner) external view returns (uint256);
/**
* @notice Get the approved address for a single NFT
* @dev Throws if `tokenId` is not a valid NFT.
* @param tokenId The NFT to find the approved address for
* @return The approved address for this NFT, or the zero address if there is none
*/
function getApproved(uint256 tokenId) external view returns (address);
/**
* @dev Checks if an operator is approved for all tokens of a given owner.
* @param owner The address of the token owner.
* @param operator The address of the operator to check.
*/
function isApprovedForAll(
address owner,
address operator
) external view returns (bool);
/**
* @dev Returns the remaining number of tokens that spender will be allowed to spend on behalf of owner.
* @param owner The address of the token owner.
* @param spender The address of the spender.
*/
function allowance(
address owner,
address spender
) external view returns (uint256);
/**
* @dev Returns the array of ERC-721 token IDs owned by a specific address.
* @param owner The address to query the tokens of.
*/
function owned(address owner) external view returns (uint256[] memory);
/**
* @dev Returns the address that owns a specific ERC-721 token.
* @param tokenId The token ID.
*/
function ownerOf(uint256 tokenId) external view returns (address erc721Owner);
/**
* @dev Returns the URI for a specific ERC-721 token.
* @param tokenId The token ID.
*/
function tokenURI(uint256 tokenId) external view returns (string memory);
/**
* @dev Approve or disapprove the operator to spend or transfer all of the sender's tokens.
* @param spender The address of the spender.
* @param amountOrId The amount of ERC-20 tokens or ID of ERC-721 tokens.
*/
function approve(
address spender,
uint256 amountOrId
) external returns (bool);
/**
* @dev Set or unset the approval of an operator for all tokens.
* @param operator The address of the operator.
* @param approved The approval status.
*/
function setApprovalForAll(address operator, bool approved) external;
/**
* @dev Transfer ERC-20 tokens or ERC-721 token from one address to another.
* @param from The address to transfer ERC-20 tokens or ERC-721 token from.
* @param to The address to transfer ERC-20 tokens or ERC-721 token to.
* @param amountOrId The amount of ERC-20 tokens or ID of ERC-721 tokens to transfer.
*/
function transferFrom(
address from,
address to,
uint256 amountOrId
) external returns (bool);
/**
* @notice Transfers the ownership of an NFT from one address to another address
* @dev Throws unless `msg.sender` is the current owner, an authorized
* operator, or the approved address for this NFT. Throws if `_rom` is
* not the current owner. Throws if `_to` is the zero address. Throws if
* `tokenId` is not a valid NFT. When transfer is complete, this function
* checks if `to` is a smart contract (code size > 0). If so, it calls
* `onERC721Received` on `to` and throws if the return value is not
* `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`.
* @param from The current owner of the NFT
* @param to The new owner
* @param tokenId The NFT to transfer
* @param data Additional data with no specified format, sent in call to `to`
*/
function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external payable;
/**
* @notice Transfers the ownership of an NFT from one address to another address
* @dev This works identically to the other function with an extra data parameter,
* except this function just sets data to "".
* @param from The current owner of the NFT
* @param to The new owner
* @param tokenId The NFT to transfer
*/
function safeTransferFrom(address from, address to, uint256 tokenId) external payable;
/**
* @dev Transfer ERC-20 tokens to an address.
* @param to The address to transfer ERC-20 tokens to.
* @param amount The amount of ERC-20 tokens to transfer.
*/
function transfer(address to, uint256 amount) external returns (bool);
/**
* @dev Retrieves the unit value associated with the token.
* @return The unit value.
*/
function getUnit() external view returns (uint256);
/**
* @dev Converts ERC-721 token to ERC-20 tokens.
* @param tokenId The unique identifier of the ERC-721 token.
*/
function erc721ToERC20(uint256 tokenId) external;
/**
* @dev Converts ERC-20 tokens to an ERC-721 token.
* @param amount The amount of ERC-20 tokens to convert.
*/
function erc20ToERC721(uint256 amount) external;
}
```
## Rationale

Common Interface for Different Token Types:

- Introduces a unified interface to address the fragmentation caused by separate [ERC-20](./eip-20.md) and [ERC-721](./eip-721.md) standards.
- Standardizes functions like transferFrom, mint, and burn, enabling developers to interact with both token types without implementing distinct logic.

Transfer Functionality:

- Includes transferFrom function for seamless movement of tokens between addresses, as it's a core component of both [ERC-20](./eip-20.md) and [ERC-721](./eip-721.md) standards.

Minting and Burning:

- Incorporates mint and burn functions for creating and destroying tokens, essential for managing token supply and lifecycle.

Balance and Ownership Queries:

- Provides functions like balanceOf and ownerOf for retrieving token balances and ownership information, crucial for both [ERC-20](./eip-20.md) and [ERC-721](./eip-721.md) tokens.

Compatibility and Extensibility:

- Ensures compatibility with existing [ERC-20](./eip-20.md) and [ERC-721](./eip-721.md) implementations, minimizing disruption during transition.
- Allows extension with additional functions and events for future enhancements.

Security Considerations:

- Implements mechanisms to prevent common issues like reentrancy attacks and overflows, ensuring the security and robustness of the unified interface.



## Backwards Compatibility


The proposed this proposal introduces a challenge in terms of backward compatibility due to the distinct balance query mechanisms utilized by [ERC-20](./eip-20.md) and [ERC-721](./eip-721.md) standards. [ERC-20](./eip-20.md) employs `balanceOf` to check an account's token balance, while [ERC-721](./eip-721.md) uses `balanceOf` to inquire about the quantity of tokens owned by an account. To reconcile these differences, the ERC must consider providing either two separate functions catering to each standard or adopting a more generalized approach.

### Compatibility Points

The primary compatibility point lies in the discrepancy between [ERC-20](./eip-20.md)'s balanceOf and [ERC-721](./eip-721.md)'s balanceOf functionalities. Developers accustomed to the specific balance query methods in each standard may face challenges when transitioning to this proposal.

### Proposed Solutions

Dual Balance Query Functions:

Introduce two distinct functions, `erc20BalanceOf` and `erc721TotalSupply`, to align with the conventions of [ERC-20](./eip-20.md) and [ERC-721](./eip-721.md), respectively. Developers can choose the function based on the token type they are working with.

## Test Cases


## Reference Implementation

- this proposal standard undergoes thorough testing to ensure consistent and accurate behavior in both [ERC-20](./eip-20.md) and [ERC-721](./eip-721.md) modes.
- Detailed documentation and sample code are provided to assist developers in understanding and implementing the this proposal standard.


## Security Considerations

- Due to the dual nature of this proposal, potential differences in protocol interpretation may arise, necessitating careful consideration during development.
- Comprehensive security audits are recommended, especially during mode transitions by users, to ensure the safety of user assets.


## Copyright

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

0 comments on commit dc82165

Please sign in to comment.