ERC-2981: Diving Into the Royalty Standard and How It Can Be Properly Implemented

Wyatt Chamberlin
Coinmonks

--

Photo by Nenad Novaković on Unsplash

Understanding NFT Royalties

Imagine a world where creators benefit from their work years after completion. A world in which they can focus solely on doing what they love because they receive adequate funding. As consumers, we could confidently support our favorite creators. What an exciting thought! With the revolutionary technology of Ethereum, this is now possible through what is known as non-fungible tokens (NFTs). NFTs allow for the possibility of ongoing creator royalties. With this, each time an NFT exchanges between collectors, the NFT creator retains a share of that monetary exchange. This concept has taken the world by storm because it enables the continuous funding of creators. So, how are these royalties actually enforced? Let us dive in.

The Need for ERC-2981

In the beginning, royalty implementations only existed at the marketplace level. However, it soon became apparent that this created a problem. Each marketplace had their own unique royalty implementation that was not easily compatible or usable by other marketplaces. As a result, artists would only receive their respective payouts on one particular marketplace and not on any other. It soon became evident that we needed,

“A standardized way to retrieve royalty payment information for non-fungible tokens (Burkes et al.).”

Enter ERC-2981: a revolutionary token standard that addresses this very concern. In this exploration, we delve into how to properly implement this standard so that we can reward NFT creators across many different marketplaces.

The Power of Simplicity in ERC-2981

ERC-2981 has a simple design to enable others to build upon this standard, vastly improving the NFT landscape.

“This ERC should be considered a minimal, gas-efficient building block for further innovation in NFT royalty payments (Burkes et al.).”

Furthermore, the simplicity makes it easier for NFT marketplaces to adopt this standard and for developers to incorporate it into their code. This strategic approach not only encourages swift implementation but also sets the stage for an ecosystem of creative possibilities that has the potential to revolutionize the world of NFTs.

Technical Specifications

Now, even though the simple design of this standard allows for easy implementation, we must still abide by certain specifications for compliance:

  1. The ERC-2981 royalty standard requires two functions: royaltyInfo() and the supportsInterface() function from IERC165, as seen below.

The following code is pulled directly from the ERC-2981: NFT Royalty Standard

2. The royaltyAmount must be calculated as a percentage of the _salePrice.

3. Since this standard allows for use of any unit of exchange, the royaltyAmount returned must not be a fixed amount.

To delve further into these specifications, refer to the EIP.

Implementing ERC-2981: A Safe Approach with OpenZeppelin

Luckily for developers, implementing this token standard is as easy as importing OpenZeppelin’s ERC-2981 contract. In doing this, developers are automatically complying with all of the necessary specifications.

Here is an easy three-step process to implement the royalty standard on an ERC-1155 NFT smart contract (NOTE: these steps also work for ERC-721 smart contracts):

  1. Import OpenZeppelin’s ERC-2981 contract and inherit its functions with the is keyword.
import "@openzeppelin/contracts/token/common/ERC2981.sol";

contract RoyaltyContract is ERC1155, ERC1155Supply, ERC2981 {

2. Call the _setDefaultRoyalty(address receiver, uint96 feeNumerator) function, inherited from the ERC-2981 contract, in the constructor to set the royalty information on deployment or create a function to set this information later.

constructor(
string memory initialUri,
uint96 feeNumerator,
address receiver,
string memory _name,
string memory _symbol
) ERC1155(initialUri) {
_setDefaultRoyalty(receiver, feeNumerator);
name = _name;
symbol = _symbol;
}

//Optional. If implementing this function, ensure there is access control, such as onlyOwner
function setDefaultRoyalty(address _receiver, uint96 _feeNumerator) public onlyOwner {
_setDefaultRoyalty(_receiver, _feeNumerator);
}

3. When using OpenZeppelin’s ERC-2981 contract while also inheriting either their ERC-1155 or their ERC-721 contracts, an issue such as this might arise:

TypeError: Derived contract must override function “supportsInterface.” Two or more base classes define function with same name and parameter types.

This error results due to the fact that ERC-2981 overrides the supportsInterface() function, and so does the ERC-1155 and ERC-721 contracts. The solution is to override the function again in the NFT smart contract.

function supportsInterface(bytes4 interfaceId) public view virtual override(ERC1155, ERC2981) returns (bool) {
return super.supportsInterface(interfaceId);
}
  • The supportsInterface function is overridden by specifying the overridden contracts as ERC1155 and ERC2981.
  • The super.supportsInterface(interfaceId) call ensures that the function works as expected by delegating to the implementation in the parent contracts.

If creating an ERC-721 contract, replace ERC1155 with ERC721.

function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721, ERC2981) returns (bool) {
return super.supportsInterface(interfaceId);
}

That is it!

Following these three steps will result in an ERC-2981 compliant NFT. The contract below is an example of what this would look like on an ERC-1155 smart contract:

By using OpenZeppelin’s ERC-2981 contract, we have a safe approach to complying with the NFT royalty standard.

Conclusion

The advancing NFT landscape has led to innovative business models such as ongoing NFT royalties. These royalties continue to support creators of all kinds for as long as their creations exist on-chain. However, the distribution of these royalties was determined at the marketplace level, ultimately leading to inconsistencies across different marketplaces. Consequently, the need for ERC-2981 came about, which enabled the continuous funding of these creators. Let us continue to support this token standard through practical application. OpenZeppelin’s battle-tested ERC-2981 contract makes doing so easy and reliable. Above all, it also contributes to the success of the NFT royalty standard and leads to widespread adoption amongst diverse marketplaces.

Citations

Zach Burks (@vexycats), James Morgan (@jamesmorgan), Blaine Malone (@blmalone), James Seibel (@seibelj), “ERC-2981: NFT Royalty Standard,” Ethereum Improvement Proposals, no. 2981, September 2020. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-2981.

Morgan, James. “EIP-2981 — Simple and Effective Royalty Standards for All.” Medium, 9 Dec. 2022, medium.com/@james.morgan/eip-2981-simple-and-effective-royalty-standards-for-all-dbd0b761a0f0.

Thank you for taking the time to read this article. When personally implementing this token standard into my projects, I came across issues that could have easily been avoided if I had a reliable resource to follow. If you found this valuable, connect with me on the following platforms:

Your engagement and feedback are greatly appreciated.

--

--

Wyatt Chamberlin
Coinmonks
0 Followers
Writer for

Fullstack and Solidity Developer | Web3 Security Reseacher