DEV Community

Andrei Slusari
Andrei Slusari

Posted on

Exploring the NFT Royalty Standard (EIP-2981)

Image description
Over the last 12 months, the non-fungible token (NFT) market has soared. We’ve seen our very own Nifty Gateway achieve explosive growth. With all this excitement, we’re eager to explore where the space is headed with a particular focus on what value an open royalty standard can bring to NFT creators.

If you ask participants in the NFT ecosystem what they’re most excited about, you’ll likely hear various different responses, such as:

  • Investing in a new asset class
  • Being part of a community
  • Opportunity to resell for profit
  • The positive long term impact of NFT technology

However, a lingering promise since the inception of NFTs, is the idea that there is now a new medium for creators to monetize their work. More specifically, royalty payments can now be seamlessly facilitated through blockchain infrastructure.

Creators have already been making use of the existing royalty payment solutions, and many have already been able to realize a newfound passive income stream. So, what’s the problem?

The NFT Royalty Landscape Today

NFT standards (ERC-721/ERC-1155) are built on Ethereum. Broadly speaking, marketplaces transfer ownership of NFTs between collectors upon a sale. These transfer mechanisms are made easy because of the open standards that exist. These standards have facilitated the proliferation of many NFTs we see today, of course with the exception of some that predated their creation e.g. CryptoPunks, CryptoKitties.

At the time of this writing, an open royalty payment standard is not ubiquitous in the Ethereum ecosystem. Royalty information is siloed to marketplaces and generally not shared. This means that if an NFT is moved off a platform and then sold, the creator won’t receive the royalties that they’re entitled to.

EIP-2981 is a standard that focuses on signaling to market participants the royalty payment information for a given NFT or set of NFTs. It allows for attaching royalty information to the token itself, thereby making use of a common data store and computation layer that all participants can access — the Ethereum blockchain.

After nearly one year of discussions, EIP-2981 was finalized on July 24, 2021.

How Does it Work?

It’s pretty simple. The crux of the problem can be solved by overriding a single Solidity function in your smart contract.

/// @notice Called with the sale price to determine how much royalty is owed and to whom.
/// @param _tokenId - the NFT asset queried for royalty information
/// @param _salePrice - the sale price of the NFT asset specified by _tokenId
/// @return receiver - address of who should be sent the royalty payment
/// @return royaltyAmount - the royalty payment amount for _salePrice

function royaltyInfo( 
    uint256 _tokenId,
    uint256 _salePrice
) external view returns (
    address receiver,
    uint256 royaltyAmount
);
Enter fullscreen mode Exit fullscreen mode

The general goal of EIP-2981 contributors is to provide a gas-efficient solution while avoiding restrictions on future royalty payment improvements. The simplicity of its design is intentional, with the aim to make adoption simple. As with any standard, adoption is key to its utility.

In the usual case, for a given NFT _tokenId and _salePrice, the royaltyInfo function will perform a percentage calculation to produce the necessary (and undisputed) information to craft a royalty payment transaction.

Notice how the function does not concern itself with currency. The existing standards for NFTs (ERC-721/1155) are currency agnostic. In fact, if we zoom out a little, NFT smart contracts aren't even aware of the concept of a "sale". When it comes to more abstract concepts like sales, it is the marketplaces that facilitate them.
As a reminder, two key actions occur when a sale takes place:

  1. A transfer of funds from the buyer to the seller
  2. A transfer of the NFT from the seller to the buyer

As far as the NFT smart contract is concerned, it can’t tell if an invocation of safeTransferFrom was a simple transfer of the NFT to another address or an actual sale event. This alone makes enforcing royalty payments on-chain challenging. Specifically when you’re conforming to existing standards that aren’t built with this in mind.

It’s important for marketplaces supporting EIP-2981 to consider the currency that the NFT sale was denominated in. The royalty calculation should be in the same denomination. So, if an NFT was sold for 45×1018 Wei (45 Ether), then the royaltyAmount returned from the function would be in the expected denomination (Wei).

With that in mind, let’s jog our memory on the fact that math in Solidity does not support fractions and suggest one possible workaround:

  1. 2.5% of the _salePrice should be sent to the receiver, we know that 2.5% of 45 Ether is 1.125 Ether. However, Solidity will compute 1 Ether:

uint256 result = (uint256(45) * 250) / 10000;

  1. More precision is required, so we can convert Ether to Wei; 45 Ether is now 45×1018 Wei and Solidity will compute 1.125×1018 Wei or 1.125 Ether:

uint256 result = (45000000000000000000 * 250) / 10000;

This highlights a potential pitfall that Solidity engineers should be no stranger to. That is, the _salePrice should be sent in the smallest denomination of the currency tendered. This reduces the likelihood of disputes with respect to how Solidity performs arithmetic operations. To further ensure that precision is kept, implementers should consider using basis points (bps). Notice how 2.5% is denoted as 250 bps and 100% is 10,000 bps. This common unit of measure for percentage interest rates in finance works well here.

In addition to this, it’s advised to extensively unit test this function before deploying to production. Call sites invoking this function can also check that the royaltyAmount value that was calculated is sensible e.g. royaltyAmount < _salePrice.

Image description

EIP-2981 in Action

A nice example of EIP-2981 in action can be found at this example . Here we can see royalties implemented on a per token basis. In contrast, we can also see globally applied royalties, where every token is associated with the same royalty information. This can be achieved relatively easily with some small tweaks to the smart contract.

The cryptocurrency space is known for pushing the boundaries and testing assumptions of existing systems. EIP-2981 is no exception — engineers and enthusiasts can get creative with how the royaltyInfo function is implemented. Some interesting approaches might include:

  • Fixed royalties — this is expected to be the common case where a static percentage is used for every sale.
  • Decaying royalties — reduce royalties owed for every transfer event of the NFT over time.
  • Multisig royalties — the receiver address could be a multisig smart contract. It may represent a DAO or some effort towards public goods funding.
  • Stepped royalties — don’t send royalties if the sale price is below a threshold.

Many contributors see this standard as a necessary building block towards a more open royalties system. For the most part, there's a particular focus on socially enforced royalties; a system where incentives between participants align such that leaving royalties unpaid is disincentivized. It’s a common belief that this approach could prove to be very resilient, and further reinforced by more transparency with respect to royalty payment obligations.

What Next?

For EIP-2981 to become widely supported we must raise awareness. Gentle forces can be applied to marketplaces by artists who request it. In addition to this, marketplaces can also anticipate the demand and implement it sooner.

All things considered, marketplaces will decide on a case-by-case basis whether to support the EIP-2981 standard. With some familiar names in the NFT landscape already supporting it, we’re optimistic others will follow.

We see this as an exciting development and one to keep a close eye on in the coming months.
Onward and Upward!

Discussion (0)