The dual-layer token combines the functionalities of ERC-20, ERC-721, and ERC-1155 while adding a classification layer that uses mainId as the main asset type identifier and subId as the unique attributes or variations of the main asset.

The proposed token aims to offer more granularity in token management, facilitating a well-organized token ecosystem and simplifying the process of tracking tokens within a contract. This standard is particularly useful for tokenizing and enabling the fractional ownership of Real World Assets (RWAs). It also allows for efficient and flexible management of both fungible and non-fungible assets.
The following are examples of assets that the DLT standard can represent fractional ownership of:
The ERC-1155 standard has experienced considerable adoption within the Ethereum ecosystem; however, its design exhibits constraints when handling tokens with multiple classifications, particularly in relation to Real World Assets (RWAs) and fractionalization of assets.
This EIP strives to overcome this limitation by proposing a token standard incorporating a dual-layer classification system, allowing for enhanced organization and management of tokens, especially in situations where additional sub-categorization of token types is necessary.
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174.
DLTReceiver InterfaceSmart contracts MUST implement all the functions in the DLTReceiver interface to accept transfers.
The two-level classification system introduced in this EIP allows for a more organized token ecosystem, enabling users to manage and track tokens with greater granularity. It is particularly useful for projects that require token classifications beyond the capabilities of the current ERC-1155 standard.
As assets can have various properties or variations, our smart contract design reflects this by assigning a mainId to each asset category and a unique subId to each derivative or sub-category. This approach expands the capabilities of ERC-1155 to support a broader range of assets with complex requirements. Additionally, it enables tracking of mainBalance for the main asset and subBalance for its sub-assets individual accounts.
The contract can be extended to support the use of subIds in two ways:
DLT provides a more versatile solution compared to other token standards such as ERC-20, ERC-721, and ERC-1155 by effectively managing both fungible and non-fungible assets within the same contract.
The following are questions that we considered during the design process:
No backward compatibility issues found.
The test suite covers:
mainId and subId combinations and verifying subBalanceOf reflects correct amountsbalanceOfBatch with array parity validationsafeTransferFrom between EOAs with balance and allowance checkssafeTransferFrom to contract recipients implementing IDLTReceiver, verifying onDLTReceived callbackapprove for specific (mainId, subId) pairs and setApprovalForAll for operator-level accesstype(uint256).max infinite approval patternsafeBatchTransferFrom with array length validationA reference implementation is provided in DLT.sol.
The implementation includes:
DLT.sol: Core token contract implementing the IDLT interface with dual-layer balance tracking, approval management, safe transfers with receiver callbacks, and batch operations.IDLT.sol: The interface as specified above.IDLTReceiver.sol: Receiver interface for safe transfer callbacks.The reference implementation uses a nested mapping mapping(uint256 mainId => mapping(address => mapping(uint256 subId => uint256))) for balance storage, enabling O(1) lookups for any (account, mainId, subId) tuple. Allowances follow the same pattern with an additional spender dimension.
The dual-layer allowance system inherits the same approve/transferFrom race condition present in ERC-20. If an owner changes an allowance from N to M, the spender may be able to spend both N and M. Implementers SHOULD provide increaseAllowance and decreaseAllowance helper functions or use the check-set pattern where the owner first sets allowance to zero before setting the new value.
The safeTransferFrom function calls onDLTReceived on the recipient contract after updating balances. This follows the checks-effects-interactions pattern, but implementers extending the base contract SHOULD be aware that the recipient callback executes with updated state. Contracts that override _beforeTokenTransfer or _afterTokenTransfer hooks must not introduce external calls that could create reentrancy paths.
safeBatchTransferFrom and balanceOfBatch iterate over unbounded arrays. Callers MUST ensure the array lengths do not exceed block gas limits. Implementations MAY impose an upper bound on array length to prevent out-of-gas failures in on-chain contexts.
While individual subBalance values are tracked per (mainId, subId) pair, any aggregation of balances across sub-IDs (e.g., computing a total mainBalance) must account for potential overflow when summing multiple uint256 values. The reference implementation tracks main balances separately to avoid this.
Copyright and related rights waived via CC0.