ERC-7401D is a simplified implementation of the ERC-7401 standard for nestable Non-Fungible Tokens (NFTs), designed for trusted ecosystems. This implementation focuses on user experience by reducing the number of transactions needed to manage nested NFTs and on security by creating a controlled environment where only trusted collections can interact.
This implementation is used by the Doodles Avatar and Doodles Wearable contracts.
ERC-7401D was built to optimize for specific use cases and makes several important deviations from the ERC-7401 implementation by RMRK Team.
The standard ERC-7401 is open and permissionless, allowing any contract to nest or be nested. ERC-7401D introduces a whitelisting mechanism for contract interactions. A token can only be nested into a contract that is a registered parent, and a contract can only add a child if it is a registered child contract.
This provides a more controlled and secure environment, preventing unauthorized or spam NFTs from being attached to tokens within the ecosystem.
The standard ERC-7401 uses a two-step process for adding children to a parent token:
- Propose (
addChild
): Anyone can "propose" a child to a parent token. This adds the child to a temporary pending list. - Commit (
acceptChild
): The parent token's owner must explicitly accept the child, moving it from the pending list to the active list.
ERC-7401D completely removes this "propose-commit" pattern. The addChild
function directly adds a child to the list of active children. As a result, the acceptChild
and rejectAllChildren
functions are not supported and will revert if called. This simplifies the nesting process and reduces gas costs. Any token from a whitelisted collection can be transferred in without requiring explicit approval for each one.
The way child tokens are tracked is fundamentally different.
- Standard ERC-7401: Uses two arrays for each parent token:
_activeChildren
and_pendingChildren
. Both storeChild
structs, which contain the child'stokenId
andcontractAddress
. This makes it easy to retrieve a list of all children, but requires iterating through the array to find children of a specific contract. - ERC-7401D: Uses a single mapping that groups children by
parentId
and then by theirchildAddress
.
// Standard ERC-7401: Separate mappings for pending and active children
mapping(uint256 => Child[]) internal _activeChildren;
mapping(uint256 => Child[]) internal _pendingChildren;
// ERC-7401D: Single mapping grouped by contract address
mapping(uint256 => mapping(address => uint256[])) _children;
This structure is much more gas-efficient for fetching all children from a specific collection under a parent (childrenOf(parentId, childAddress)
).
pragma solidity ^0.8.26;
import "./ERC7401D.sol";
contract DoodlesWearable is ERC7401D {
constructor(address parentAddress) ERC7401D("Doodles Wearables", "WEARABLES") {
_addParentAddress(parentAddress);
}
function mint(address to, uint256 tokenId) external {
_mint(to, tokenId, "");
}
}
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.
This implementation is built upon the work of the RMRK Team, who created the original ERC-7401 standard and reference implementation.
Disclaimer: This software is provided "as is" without warranties. Use at your own risk.