akash11

ERC-2981: The NFT Royalty Standard

A technical standard that allows NFT creators to receive automatic royalty payments whenever their tokens are resold, embedding royalty information directly into the smart contract.

Published on 22 November, 2025

Categories:

SolidityToken

What Problem Does ERC-2981 Solve?

Before ERC-2981, NFT marketplaces had no standardized way to determine royalty payments. Each platform implemented royalties differently, or didn't support them at all. Creators relied on individual marketplaces honoring royalty agreements, with no guarantee their work would generate ongoing revenue from secondary sales.
ERC-2981 fixes this by providing a standard interface that any marketplace can query to determine the correct royalty amount and recipient address for a given token sale.

The Core Interface

The standard defines a simple interface with one required function:
interface IERC2981 { function royaltyInfo( uint256 tokenId, uint256 salePrice ) external view returns ( address receiver, uint256 royaltyAmount ); }
When a marketplace sells an NFT, it calls royaltyInfo() with the token ID and sale price. The contract returns two pieces of information: who should receive the royalty payment and how much they should receive.

How It Works in Practice

Let's walk through a real transaction:
  1. A collector purchases NFT #42 for 10 ETH on a marketplace
  2. The marketplace calls royaltyInfo(42, 10000000000000000000) on the NFT contract
  3. The contract returns (0xCreatorAddress, 500000000000000000) indicating 0.5 ETH royalty
  4. The marketplace sends 0.5 ETH to the creator and 9.5 ETH to the seller
Here's a basic implementation:
contract MyNFT is ERC721, ERC2981 { constructor() ERC721("MyNFT", "MNFT") { // Set 5% royalty to contract deployer _setDefaultRoyalty(msg.sender, 500); } function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721, ERC2981) returns (bool) { return super.supportsInterface(interfaceId); } }
The 500 represents 5% in basis points (5% = 500/10000). This is the standard way to express percentages in Solidity to avoid decimals.

Per-Token vs Default Royalties

ERC-2981 supports two royalty models:
Default Royalty: Every token in the collection uses the same royalty percentage and recipient.
_setDefaultRoyalty(creatorAddress, 750); // 7.5% for all tokens
Per-Token Royalty: Each token can have unique royalty settings.
_setTokenRoyalty(tokenId, specificCreator, 1000); // 10% for token #1 _setTokenRoyalty(tokenId, anotherCreator, 250); // 2.5% for token #2
This flexibility allows for collections where different artists collaborate, each receiving royalties only from their specific pieces.

The Basis Points System

Royalties use basis points to represent percentages:
1 basis point = 0.01%
100 basis points = 1%
1000 basis points = 10%
10000 basis points = 100%
Example calculations:
// For a 2 ETH sale with 5% royalty (500 basis points) salePrice = 2 ETH = 2000000000000000000 wei royaltyAmount = (2000000000000000000 * 500) / 10000 royaltyAmount = 100000000000000000 wei = 0.1 ETH

Important Limitations

Not Enforceable: The standard provides information but cannot force marketplaces to pay royalties. A marketplace can query the royalty info and simply ignore it. This is a fundamental limitation of the design.
No Multi-Recipient Support: The interface returns a single receiver address. For splitting royalties among multiple creators, you need a separate payment splitter contract.
contract PaymentSplitter { // Receives royalties and distributes to multiple addresses mapping(address => uint256) public shares; function release(address payable account) public { // Calculate and send their share } }
Marketplace Dependency: The standard only works if marketplaces implement the check and payment logic. Major platforms like OpenSea, Rarible, and LooksRare support it, but smaller or decentralized exchanges might not.

Implementation Example

Here's a complete NFT contract with configurable royalties:
contract ArtCollection is ERC721, ERC2981 { uint256 private _tokenIds; constructor() ERC721("Art Collection", "ART") {} function mint(address to) public returns (uint256) { _tokenIds++; _safeMint(to, _tokenIds); // Set 2.5% royalty for this token _setTokenRoyalty(_tokenIds, to, 250); return _tokenIds; } function updateRoyalty(uint256 tokenId, address receiver, uint96 feeNumerator) external { require(ownerOf(tokenId) == msg.sender, "Not token owner"); _setTokenRoyalty(tokenId, receiver, feeNumerator); } function supportsInterface(bytes4 interfaceId) public view override(ERC721, ERC2981) returns (bool) { return super.supportsInterface(interfaceId); } }

Checking Royalty Support

Marketplaces should verify a contract implements ERC-2981 before attempting to query royalty information:
bytes4 private constant _INTERFACE_ID_ERC2981 = 0x2a55205a; function checkRoyaltySupport(address nftContract) public view returns (bool) { try IERC165(nftContract).supportsInterface(_INTERFACE_ID_ERC2981) returns (bool supported) { return supported; } catch { return false; } }
The interface ID 0x2a55205a is derived from the function signature of royaltyInfo() and is used for ERC-165 interface detection.

Gas Considerations

The royaltyInfo() function is a view function, meaning it doesn't cost gas to call. Marketplaces can query royalty information off-chain before constructing the sale transaction. The actual royalty payment happens as a standard ETH or token transfer within the sale transaction.

Real World Adoption

Major NFT marketplaces have integrated ERC-2981 with varying levels of enforcement. OpenSea initially made royalties optional in 2022, then introduced the Operator Filter Registry to help creators enforce royalties by blocking transfers through non-compliant marketplaces. This created an ongoing debate about creator rights versus marketplace freedom in the NFT ecosystem.
The standard succeeded in creating a common language for royalty information but cannot solve the enforcement problem at the protocol level. That requires either social consensus among marketplaces or additional tooling like transfer restrictions.

Conclusion

ERC-2981 provides a standardized interface for NFT royalty information, allowing contracts to specify royalty recipients and amounts in a marketplace-agnostic way. While it cannot enforce payment, it establishes the technical foundation that well-intentioned platforms can implement to support creator revenue from secondary sales.

Copyright © 2025

Akash Vaghela