ERC2981 Explained in Detail
ERC2981 defines royaltyInfo(tokenId, salePrice). The function returns a receiver and a royalty amount based on the sale price.
The standard only reports royalty information. It does not detect sales, transfer funds, or force a marketplace to pay.
Smart contract example
(address receiver, uint256 amount) = royaltyInfo(tokenId, 1 ether);
The royalty amount should use the same unit as the sale price.
ERC2981 in Auditing
Royalty code often looks harmless, but it can break marketplace integrations or expose admin controls. Incorrect royalty math can overcharge, undercharge, or return unusable receiver data.
Auditors also check whether mutable royalty settings have proper access control.
Red flags in code
-
Royalty amount is fixed instead of scaling with sale price.
-
Royalty can exceed the sale price.
-
Receiver can be set to an invalid or unexpected address.
-
ERC165 support for ERC2981 is missing.
-
Transfers try to enforce royalties on every wallet-to-wallet movement.
How to test or review it
-
Test
royaltyInfowith zero, small, normal, and large sale prices. -
Check default royalties and per-token overrides.
-
Verify rounding and maximum royalty bounds.
-
Test admin and non-admin royalty updates.
-
Confirm ERC721, ERC1155, and ERC2981 interface support is accurate.
Keep learning this topic
ERC721
ERC721 is the Ethereum token standard for non-fungible tokens where each token ID represents a unique asset with one owner.
ERC1155
ERC1155 is a multi-token standard that supports many fungible and non-fungible token IDs in one contract.
supportsInterface
supportsInterface is the ERC165 function that returns whether a contract claims support for a given interface ID.
Practice this in real audit scenarios
Definitions help, but auditors need reps. SCH turns concepts like ERC2981 into exploit labs, code review habits, and report-writing practice.
Start the free trial or see the full smart contract auditing course.