Free 30-min Web3 Consultation
Book Consultation
Smart Contract Security Audits
View Audit Services
Custom DeFi Protocol Development
Explore DeFi
Full-Stack Web3 dApp Development
View App Services
Free 30-min Web3 Consultation
Book Consultation
Smart Contract Security Audits
View Audit Services
Custom DeFi Protocol Development
Explore DeFi
Full-Stack Web3 dApp Development
View App Services
Free 30-min Web3 Consultation
Book Consultation
Smart Contract Security Audits
View Audit Services
Custom DeFi Protocol Development
Explore DeFi
Full-Stack Web3 dApp Development
View App Services
Free 30-min Web3 Consultation
Book Consultation
Smart Contract Security Audits
View Audit Services
Custom DeFi Protocol Development
Explore DeFi
Full-Stack Web3 dApp Development
View App Services
LABS
Guides

Setting Up a Royalty Distribution System for NFT Collections

A technical guide for developers to implement on-chain royalty enforcement, multi-recipient fee splitting, and automated payment streams for NFT collections.
Chainscore © 2026
introduction
FUNDAMENTALS

Setting Up a Royalty Distribution System for NFT Collections

A technical guide to implementing on-chain royalty enforcement and automated revenue sharing for NFT projects.

NFT royalties are a percentage of a secondary sale price paid to the original creator or rights holder. While marketplaces like OpenSea historically enforced these fees off-chain, the shift towards decentralized, on-chain enforcement is critical for creator sustainability. This guide covers the core concepts of building a robust royalty system using EIP-2981: NFT Royalty Standard and smart contract logic to programmatically split revenue between creators, collaborators, and treasuries.

The foundation for modern on-chain royalties is EIP-2981. This Ethereum standard defines a simple interface—royaltyInfo(uint256 tokenId, uint256 salePrice)—that returns a recipient address and royalty amount for a given token and sale price. Implementing this in your NFT's smart contract ensures any marketplace or protocol that supports the standard can query and pay royalties automatically. It moves enforcement from platform policy to immutable code.

For multi-party distributions, you need a payment splitter. A common pattern is to deploy a contract that receives the royalty payments and distributes them according to predefined shares. For example, a project might allocate 50% to the lead artist, 30% to a development DAO, and 20% to a community treasury. Using OpenZeppelin's PaymentSplitter or a custom implementation ensures transparent, trustless, and gas-efficient distribution to all stakeholders.

Consider an NFT collection where tokenId #1 sells for 1 ETH on a compliant marketplace. The marketplace calls the royaltyInfo function, which specifies a 5% royalty (0.05 ETH) payable to the RoyaltyDistributor contract. This distributor then splits the 0.05 ETH, sending 0.025 ETH to the artist's wallet, 0.015 ETH to the developer multisig, and 0.01 ETH to the project's Gnosis Safe. This entire flow is automated and verifiable on-chain.

Key design decisions include choosing a royalty percentage (typically 5-10%), defining immutable vs. updatable recipient logic, and handling edge cases like royalty payments in different ERC-20 tokens. It's also crucial to test your implementation against popular marketplace contracts and consider using modular standards like EIP-2981 alongside Manifold's Royalty Registry for maximum compatibility across the ecosystem.

prerequisites
SETUP

Prerequisites

Before building an on-chain royalty distribution system, you need a foundational understanding of the core technologies and tools involved.

This guide assumes you have a working knowledge of Ethereum or an EVM-compatible blockchain like Arbitrum or Polygon. You should be comfortable with core concepts such as wallets, gas fees, and transaction finality. A basic understanding of ERC-721 and ERC-1155 token standards is essential, as these define the NFT collections you'll be managing. You'll also need to grasp how smart contracts function as the immutable, self-executing backend for your system.

You must set up a development environment. This includes installing Node.js (v18 or later) and a package manager like npm or yarn. You will use the Hardhat or Foundry framework for writing, testing, and deploying your contracts. Familiarity with Solidity (v0.8.x) is required for writing the distribution logic. You'll also need access to a blockchain node for testing; you can use a local Hardhat network, a testnet like Sepolia, or a service like Alchemy or Infura.

For interacting with your contracts and managing funds, you need a secure wallet with test ETH. MetaMask is the most common choice. You should understand how to export your wallet's private key or mnemonic phrase for use in scripts, but always keep this information secure and never commit it to version control. Tools like dotenv are used to manage environment variables for your private keys and RPC URLs safely.

The royalty distribution logic itself requires specific data. You must have a clear mapping of payees (e.g., creator wallets, DAO treasuries) and their respective share percentages, which must sum to 100%. You also need to decide on the payment token—typically the chain's native currency (ETH, MATIC) or a stablecoin like USDC. Your contract will need the token's contract address to handle transfers correctly.

Finally, consider the operational aspects. You will need a method to fund the distribution contract with the accrued royalties, which could be manual transfers or an automated process from a marketplace or secondary sales contract. Planning for upgradeability via proxies or designing a immutable, one-time deployment is a critical architectural decision that must be made before writing the first line of code.

eip2981-implementation
DEVELOPER GUIDE

Implementing the EIP-2981 Royalty Standard

A technical guide for NFT creators and developers on integrating on-chain royalties into smart contracts using the EIP-2981 standard.

EIP-2981 is a royalty standard for NFTs that defines a simple, universal interface for marketplaces to query royalty payment information. Before its adoption, royalty enforcement was fragmented, relying on individual marketplace policies. This standard allows the NFT's smart contract itself to declare how much should be paid to the original creator or rights holder upon each secondary sale. The core function is royaltyInfo(uint256 _tokenId, uint256 _salePrice), which returns the recipient address and the royalty amount for a given sale price. This creates a trustless, on-chain mechanism for creator compensation.

To implement EIP-2981, your NFT contract—typically an ERC-721 or ERC-1155—must inherit from and implement the IERC2981 interface. The key step is writing the royaltyInfo function logic. A common pattern is to store a global royalty percentage and recipient for the entire collection. For example, you might set a 5% royalty sent to the contract deployer. More advanced implementations can support per-token royalty settings, allowing unique royalty rules for individual NFTs within the same collection, though this increases gas costs and complexity.

Here is a basic Solidity implementation snippet for a fixed, collection-wide royalty:

solidity
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/interfaces/IERC2981.sol";

contract RoyaltyNFT is ERC721, IERC2981 {
    address public royaltyRecipient;
    uint256 public royaltyBps; // Basis points (e.g., 500 for 5%)

    constructor(uint256 _royaltyBps) ERC721("RoyaltyNFT", "RNFT") {
        royaltyRecipient = msg.sender;
        royaltyBps = _royaltyBps;
    }

    function royaltyInfo(uint256 /*_tokenId*/, uint256 _salePrice)
        external
        view
        override
        returns (address receiver, uint256 royaltyAmount)
    {
        receiver = royaltyRecipient;
        royaltyAmount = (_salePrice * royaltyBps) / 10000;
    }

    function supportsInterface(bytes4 interfaceId)
        public
        view
        virtual
        override(ERC721, IERC165)
        returns (bool)
    {
        return
            interfaceId == type(IERC2981).interfaceId ||
            super.supportsInterface(interfaceId);
    }
}

Crucially, you must also override the supportsInterface function to return true for type(IERC2981).interfaceId, signaling to marketplaces that your contract supports this standard.

After deployment, marketplace integration is not automatic. Major platforms like OpenSea, Blur, and LooksRare actively check for the EIP-2981 interface. If detected, they will use the on-chain data to facilitate royalty payments during trades. However, enforcement is not guaranteed on all platforms, and some may allow traders to override royalties. For maximum compatibility, many projects also set off-chain royalty metadata on platforms as a backup. It's essential to test your implementation on a testnet using marketplace test environments to verify the royalty is correctly calculated and paid to the designated recipient.

Considerations for advanced setups include using the EIP-2981 implementation from OpenZeppelin Contracts, which provides abstract base contracts. You should also plan for royalty governance—how can the recipient or percentage be updated if needed? This often involves adding access control (e.g., Ownable or a multisig) to functions that update royaltyRecipient and royaltyBps. Remember that while EIP-2981 provides the technical standard, the economic and legal enforceability of royalties remains an evolving aspect of the NFT ecosystem.

fee-splitting-contract
SMART CONTRACT DEVELOPMENT

Designing a Multi-Recipient Fee-Splitting Contract

A guide to building an on-chain royalty distribution system for NFT collections using Solidity, covering contract architecture, security considerations, and gas optimization.

A multi-recipient fee-splitting contract automates the distribution of revenue from NFT sales to multiple parties, such as artists, developers, and community treasuries. Unlike simple single-recipient transfers, these contracts handle complex logic for proportional splits, gas-efficient batch payments, and immutable payout rules. They are typically deployed once and configured with a fixed list of recipients and their respective shares, often expressed in basis points (e.g., 5000 for 50%). This ensures transparent and trustless execution of royalty agreements directly on-chain, removing the need for manual, off-chain calculations and payments.

The core architecture involves storing an array of payee addresses and a corresponding array of shares. When the contract receives ETH (or another native token), the release function calculates each payee's portion and transfers it. A critical pattern is using Pull over Push for withdrawals: instead of automatically sending funds to all recipients (a push), which can fail and lock funds, you allow each payee to call a function to withdraw their accumulated balance. This shifts the gas cost to the recipient and prevents failed transactions due to gas limits or non-receiving contracts. The OpenZeppelin PaymentSplitter is a widely-audited reference implementation of this pattern.

For NFT collections, you must integrate the splitter with your minting contract. The primary method is to set the splitter's address as the withdrawAddress or treasury in your NFT contract (e.g., in an ERC721A or ERC1155 implementation). All primary sale proceeds and secondary sale royalties (if enforced via an on-chain royalty standard like EIP-2981) are then sent to the splitter. Here's a simplified integration snippet:

solidity
// In your NFT contract constructor
address payable public feeSplitter;
constructor(address payable _feeSplitter) {
    feeSplitter = _feeSplitter;
}
// Function to forward funds
function withdraw() external {
    (bool success, ) = feeSplitter.call{value: address(this).balance}("");
    require(success, "Transfer failed");
}

Security is paramount. Your contract must be immune to reentrancy attacks when handling ETH transfers; use the Checks-Effects-Interactions pattern or ReentrancyGuard. Ensure share allocations sum to 10,000 basis points (100%) to prevent rounding errors or fund lockup. Consider adding a minimum threshold for withdrawals to make gas costs worthwhile for recipients. For upgradeability or emergency scenarios, you can implement a multi-signature or DAO-controlled function to replace the payee list, but this adds centralization and should be clearly documented. Always conduct thorough testing, including edge cases with many payees and small payment amounts.

Gas optimization becomes crucial with many recipients. Storing shares in a uint256 array and using a loop to calculate balances is standard, but the cost scales with the number of payees. For splits with 50+ parties, consider alternative designs like a Merkle tree distributor, where you store a Merkle root on-chain and recipients submit proofs to claim their share. This has a constant gas cost for contract deployment and updating the root. Another advanced technique is using ERC-20 wrapper tokens that represent a claim on the contract's ETH balance, allowing recipients to trade their future royalty rights on decentralized exchanges.

To deploy, write and test your contract using Foundry or Hardhat. Verify the source code on block explorers like Etherscan. For mainnet deployment, consider using a proxy pattern (e.g., Transparent Upgradeable Proxy) if you anticipate needing fixes. Document the payee addresses and shares transparently for your community. A well-designed fee splitter not only automates payouts but also serves as a verifiable commitment to your project's stakeholders, aligning incentives and building trust through code.

IMPLEMENTATION METHODS

Comparison of On-Chain Royalty Standards

A technical comparison of the primary on-chain methods for enforcing NFT creator royalties.

Feature / ProtocolEIP-2981 (Royalty Standard)ERC-721C (Configurable Royalties)Manifold Royalty Registry

Standard Type

Interface

Full Token Contract

Registry Contract

Royalty Enforcement

Royalty Flexibility

Fixed % per token

Rules-based logic per contract

Override mapping per collection

Gas Cost for Royalty Lookup

~25k gas

~30k gas

~35k gas + registry read

Marketplace Integration Complexity

Low

High

Medium

Royalty Recipient Updates

Immutable after mint

Updatable by admin

Updatable by verified creator

Primary Use Case

Simple, universal reporting

Programmable, conditional logic

Centralized fallback and overrides

automated-payment-streams
AUTOMATED PAYMENT STREAMS

Setting Up a Royalty Distribution System for NFT Collections

Learn how to implement a smart contract system that automatically distributes royalty payments to NFT creators and collaborators on every secondary sale.

A royalty distribution system is a smart contract that automatically splits and sends a percentage of every secondary NFT sale to predefined recipients. This solves a critical problem for creators: manually tracking and paying out royalties is error-prone and inefficient. Modern standards like ERC-2981 define a universal interface for on-chain royalty information, but the actual payment logic must be implemented separately. A well-designed system handles the entire flow: detecting a sale, calculating the royalty fee, and executing payments to multiple parties in a single, atomic transaction.

The core architecture involves two main components: the royalty information contract and the payment splitter contract. The royalty contract (often adhering to ERC-2981) returns the royalty amount and recipient address when queried by a marketplace. For complex splits, the recipient should be a dedicated payment splitter contract. This splitter, such as OpenZeppelin's PaymentSplitter or a custom implementation using the Solidity address payable[] and uint256[] patterns, holds the funds and allows beneficiaries to release() their share. This separation of concerns keeps the NFT contract upgradeable and gas-efficient.

Here is a basic example of a payment splitter contract that receives ETH royalties and allows for on-demand withdrawal by payees:

solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import "@openzeppelin/contracts/finance/PaymentSplitter.sol";

contract RoyaltySplitter is PaymentSplitter {
    constructor(address[] memory payees, uint256[] memory shares)
        PaymentSplitter(payees, shares)
    {}
}

Your NFT's royaltyInfo function would return the address of this deployed RoyaltySplitter and the royalty amount (e.g., 5% or 500 basis points). Marketplaces like OpenSea and Blur that support the standard will send the royalty fee directly to this contract.

For more advanced, real-time streaming of royalties, you can integrate with Sablier or Superfluid. Instead of locking funds in a splitter, these protocols create continuous payment streams. When a royalty payment arrives at a Sablier Lockup Linear stream, it is instantly and proportionally distributed to all stream recipients. This is ideal for ongoing collaborations where contributors are paid per second as sales occur. Implementing this requires your payment splitter to call the streaming protocol's createWithDurations function upon receiving funds, automating the entire process from sale to real-time distribution.

Key considerations for deployment include gas costs, upgradeability, and security. Each secondary sale will incur extra gas for the royalty transfer and splitter logic. Using a minimal proxy (ERC-1167) for your splitter can reduce deployment costs for multiple collections. To future-proof your system, consider an upgradeable pattern like the Transparent Proxy or UUPS so you can adjust payees or integrate new streaming protocols. Always conduct thorough audits on the payment logic, as handling direct ETH transfers and array-based accounting is a common attack vector for reentrancy and overflow bugs.

To implement this, follow these steps: 1) Deploy your NFT contract with an ERC-2981 royaltyInfo function. 2) Deploy a PaymentSplitter or custom distributor with your payee addresses and share percentages. 3) Point your NFT's royalty recipient to the splitter address. 4) For streaming, add logic to forward received royalties to a Sablier stream. Test extensively on a testnet like Sepolia using marketplaces' test environments. Resources include the OpenZeppelin Contracts Wizard for boilerplate and Sablier documentation for streaming integration examples.

tools-and-libraries
ROYALTY IMPLEMENTATION

Essential Tools and Libraries

Building a robust royalty system requires a combination of smart contract standards, indexers, and payment infrastructure. These tools handle the core logic, tracking, and distribution of secondary sale proceeds.

challenges-bypass-aggregation
ADDRESSING MARKETPLACE BYPASS AND CROSS-PLATFORM AGGREGATION

Setting Up a Royalty Distribution System for NFT Collections

A technical guide to implementing on-chain royalty enforcement that protects creator revenue across all marketplaces and aggregators.

NFT royalties are a critical revenue stream for creators, but they are often circumvented by marketplace bypass and cross-platform aggregation. A marketplace bypass occurs when a user transfers an NFT directly via a wallet-to-wallet transaction or a non-compliant marketplace to avoid paying the creator fee. Cross-platform aggregators like Genie or Gem further complicate enforcement by sourcing liquidity from multiple marketplaces, some of which may not enforce royalties. The core issue is that the original ERC-721 and ERC-1155 standards do not have a built-in mechanism to mandate royalty payments on secondary sales; they only suggest a royalty amount via the EIP-2981 royaltyInfo function, which marketplaces can choose to ignore.

To enforce royalties reliably, the logic must be moved on-chain into the smart contract itself. The most effective method is to implement a transfer validation hook. This involves overriding the _update function (or _beforeTokenTransfer in older implementations) to intercept all transfers and require payment of a fee to a designated address. A common approach is to integrate with a modular royalty standard like ERC-2981 for reporting and a registry like Manifold's Royalty Registry or 0xSplits for complex distribution logic. The contract checks if the transfer is a sale (e.g., by verifying the recipient has sent sufficient ETH/ERC-20 tokens) and then routes a percentage to the royalty recipient before allowing the transfer to proceed.

Here is a simplified conceptual example of an enforceable royalty mechanism in a Solidity smart contract, extending ERC-721:

solidity
function _update(address to, uint256 tokenId, address auth) internal virtual override returns (address) {
    address from = _ownerOf(tokenId);
    // Check if this is a potential sale (simplified logic)
    if (from != address(0) && to != address(0) && msg.value > 0) {
        uint256 royaltyAmount = (msg.value * royaltyBasisPoints) / 10000;
        (address recipient, ) = royaltyInfo(tokenId, msg.value);
        // Send royalty to recipient
        (bool success, ) = recipient.call{value: royaltyAmount}("");
        require(success, "Royalty transfer failed");
    }
    return super._update(to, tokenId, auth);
}

This hook ensures the fee is paid for any transfer involving value, regardless of the marketplace or interface used. For production, you must integrate with a secure payment oracle or use a more robust sale detection method to prevent false positives.

For advanced distribution—splitting royalties between multiple creators, a DAO treasury, or charity—you should delegate to a dedicated payment splitter contract. Deploy an instance of a verified PaymentSplitter or use the 0xSplits protocol. Your NFT contract's royaltyInfo function would then return the splitter contract address as the recipient. This keeps the NFT contract upgradeable and gas-efficient, as the complex distribution logic is offloaded. Always verify the splitter contract on a block explorer like Etherscan after deployment and test distribution with small amounts before minting.

Key considerations for deployment include gas costs, as on-chain checks add overhead to transfers; sale detection accuracy, to avoid taxing non-sales like gifts; and upgradeability, to adjust parameters like basis points. While this method significantly strengthens enforcement, it is not absolute—determined users could still use atomic swaps or private sales. However, it effectively closes the loophole for standard marketplace and aggregator activity, ensuring creators are compensated for the vast majority of secondary market transactions.

ENFORCEMENT MECHANISMS

Marketplace Support for On-Chain Royalties

Comparison of how major NFT marketplaces implement and enforce creator royalties.

PlatformOpenSeaBlurRaribleMagic Eden

Primary Royalty Enforcement

Operator Filter Registry

Optional Creator Fee

Protocol-Level Enforcement

Creator-Controlled Enforcement

Default Royalty Respect

On-Chain Enforcement Tool

EIP-2981

Custom Marketplace Logic

Manifold Royalty Registry

Open Creator Protocol

Royalty Bypass Possible

Secondary Sale Fee

2.5% + Royalty

0.5%

2.5% + Royalty

0% + Royalty

Supports EIP-2981

Minimum Royalty Period

Permanent

None

Permanent

Permanent

Royalty Fee Range

0-10%

0-100%

0-50%

0-100%

ROYALTY IMPLEMENTATION

Frequently Asked Questions

Common technical questions and solutions for developers building on-chain royalty systems for NFT collections.

On-chain enforcement means royalty logic is embedded in the NFT's smart contract, typically using the EIP-2981 standard's royaltyInfo function. Marketplaces that support the standard query this function to determine the fee. Off-chain enforcement relies on marketplace policy, where platforms like OpenSea use a centralized registry to look up creator-set fees, which can be ignored by other marketplaces.

The key technical difference is trust. On-chain is permissionless and verifiable by any integrated exchange, while off-chain is a centralized opt-in system. For robust enforcement, implement EIP-2981 in your ERC-721 or ERC-1155 contract. However, note that some marketplaces and aggregators may still bypass fees, making a hybrid approach with additional safeguards necessary for maximum coverage.

conclusion-next-steps
IMPLEMENTATION SUMMARY

Conclusion and Next Steps

You have now explored the core components for building a robust, on-chain royalty distribution system for your NFT collection.

This guide covered the essential architecture: a RoyaltySplitter smart contract that receives primary and secondary sales revenue, a secure withdrawal pattern for payouts, and integration with marketplaces using the EIP-2981 royalty standard. The key takeaway is that a well-designed system is trust-minimized and transparent, ensuring creators are compensated fairly without relying on centralized intermediaries. Your contract should be the single source of truth for all payouts.

For production deployment, your next steps should include: - Conducting a thorough audit with a reputable firm like OpenZeppelin or Trail of Bits. - Implementing a timelock or multi-signature wallet for administrative functions like updating payee addresses. - Writing comprehensive unit and integration tests, especially for edge cases in the _splitPayment logic. - Deploying to a testnet first (like Sepolia or Goerli) and simulating sales using tools like Tenderly or Hardhat.

To extend the system's functionality, consider integrating with decentralized payment streaming protocols like Sablier or Superfluid for real-time royalty distributions. You could also explore adding snapshot capabilities for off-chain voting on treasury usage, or building a frontend dashboard that visualizes payout history using The Graph for indexed data. Remember to verify and publish your contract source code on Etherscan to build trust with your community.

Staying updated is crucial, as royalty standards and marketplace behaviors evolve. Follow the progress of EIP-2981 extensions and new proposals like EIP-5516 for on-chain royalty enforcement. Engage with the developer community on forums like Ethereum Magicians and the NFT-specific channels in the Ethereum Discord to share insights and learn from others' implementations.

How to Set Up an NFT Royalty Distribution System | ChainScore Guides