ERC-8034 Referential NFT Royalty Distribution (Referable NFT Royalties)
Final · NFTs & multi-token · created 2025-10-02
A standard that defines how to split royalties among multiple recipients and the referenced original NFTs when NFTs linked by reference relationships (rNFTs) are sold.
Why it is needed
ERC-5521 introduced referential NFTs (rNFTs), which record the relationship in which one NFT references another as a directed acyclic graph (DAG). For example, a derivative NFT references an original NFT. However, the existing royalty standard ERC-2981 does not consider such reference structures at all, and it does not support specifying multiple recipients at a single level. As a result, even for a work made jointly by a creator and collaborators, royalties could only be sent to a single address, and when a derivative was sold there was no way for rewards to flow to the referenced original. This standard allows multiple recipients per work, splits royalties along the reference graph down to a set depth, and lets the fixed rate be queried without a sale, giving marketplaces and users a transparent reward structure.
What to implement
function supportsReferenceRoyalties() external view returns (bool);: Returns whether the contract implements this standard. Actual detection must rely on ERC-165.function royaltyNonce(address signer, address rNFTContract, uint256 tokenId) external view returns (uint256);: Returns the current nonce value to use in an EIP-712 signature. It is used when creating signatures off-chain.
In depth
Two query functions: wei and basis points
getReferenceRoyaltyInfo is overloaded in two ways. The version that takes salePrice returns the amount in wei calculated from the sale price, and it MUST return an amount of 0 when no royalty is configured or when salePrice is 0. The version without salePrice MUST return the configured rate as is in basis points (100 = 1%), and it is meant for transparently querying the fixed rate without a sale price calculation. Both versions return a ReferenceRoyalty struct that contains the primary recipient share together with the referenced NFT shares up to referenceDepth.
Configuration function and the 10% cap
setReferenceRoyalty sets the primary recipient shares through the recipients and royaltyFractions (basis points) arrays, and limits the reference propagation range with referenceDepth. The call MUST be restricted to an authorized party (for example, the rNFT contract owner), and it MUST enforce that the sum of the primary recipient rates does not exceed 1000 basis points (10%). This 10% cap applies only at the primary recipient level, while the share flowing to the reference levels is managed separately by REFERRED_ROYALTY_FRACTION and referenceDepth.
Configuration via EIP-712 signature
The signer recovered from the signature overload MUST either hold CONFIGURATOR_ROLE or be IERC721(rNFTContract).ownerOf(tokenId) at verification time. The message MUST include a nonce, and the contract MUST track, verify, and increment the nonce to prevent reuse (replay). The deadline is compared with block.timestamp, and a signature where block.timestamp > deadline MUST be rejected. The recommended domain is name "RNFTRoyalty", version "2", and the signature struct contains the keccak256 hashes of recipients and royaltyFractions. Because the signer parameter is explicit, a relayer can send the actual transaction.
Distribution model: 2% pass-through and depth limit
The primary recipient share is split by the rates in the royaltyInfos array (for example, splitting 5% into 3% and 2%). At the reference level, at each hop a share equal to REFERRED_ROYALTY_FRACTION (for example, 200bps, 2%) is taken and divided among the referenced NFTs at that depth in proportion to their configured weights, and if all weights are 0 it is split equally. referenceDepth MUST be capped (MUST), and the reference implementation enforces 3 or less (recommended). In the example, with depth 2, a primary royalty of 5% (3% + 2%), and 2 referenced NFTs at depth 1, 2% is passed on and split 1% each, so on a 100 ETH sale the creator gets 3 ether, the collaborator 2 ether, and each referenced NFT owner 1 ether.
ERC-165 discovery and independent design
Implementations MUST return true for supportsInterface(type(IRNFTRoyalty).interfaceId), and when using inheritance they SHOULD forward other interfaces through super.supportsInterface. There is also a supportsReferenceRoyalties() function, but detection must rely on ERC-165. This standard is designed as a separate contract that is independent of ERC-2981 and not tied to a token standard. It targets ERC-5521 rNFTs and in practice operates on top of ERC-721 ownership semantics. Marketplaces can integrate with just an ERC-165 check, a query function call, and optional signature-based configuration.
Things to watch out for
- Restricting configuration authority: setReferenceRoyalty must be restricted so that only a privileged role can call it, for example through AccessControl.
- The royalty cap applies only at the primary recipient level: The 10% (1000bps) cap applies only to the primary recipient rates, and the share passed to the reference levels is managed separately by REFERRED_ROYALTY_FRACTION and referenceDepth.
- Gas limits and depth limit: If referenceDepth has no upper bound (for example, 3 or less), the gas cost of the computation that follows the reference graph can grow large.
- Input validation: You must check that recipient addresses are not zero and that royalty rates are valid. You should also verify that supportsInterface is correctly forwarded to the parent contract.
- Signature replay protection: Use a nonce per signer and per (rNFT contract, token ID), and increment it after successful verification. Implementations must document the nonce scope they choose.