ERC2981.sol 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. // SPDX-License-Identifier: MIT
  2. // OpenZeppelin Contracts (last updated v4.5.0) (token/common/ERC2981.sol)
  3. pragma solidity ^0.8.0;
  4. import "../../interfaces/IERC2981.sol";
  5. import "../../utils/introspection/ERC165.sol";
  6. /**
  7. * @dev Implementation of the NFT Royalty Standard, a standardized way to retrieve royalty payment information.
  8. *
  9. * Royalty information can be specified globally for all token ids via {_setDefaultRoyalty}, and/or individually for
  10. * specific token ids via {_setTokenRoyalty}. The latter takes precedence over the first.
  11. *
  12. * Royalty is specified as a fraction of sale price. {_feeDenominator} is overridable but defaults to 10000, meaning the
  13. * fee is specified in basis points by default.
  14. *
  15. * IMPORTANT: ERC-2981 only specifies a way to signal royalty information and does not enforce its payment. See
  16. * https://eips.ethereum.org/EIPS/eip-2981#optional-royalty-payments[Rationale] in the EIP. Marketplaces are expected to
  17. * voluntarily pay royalties together with sales, but note that this standard is not yet widely supported.
  18. *
  19. * _Available since v4.5._
  20. */
  21. abstract contract ERC2981 is IERC2981, ERC165 {
  22. struct RoyaltyInfo {
  23. address receiver;
  24. uint96 royaltyFraction;
  25. }
  26. RoyaltyInfo private _defaultRoyaltyInfo;
  27. mapping(uint256 => RoyaltyInfo) private _tokenRoyaltyInfo;
  28. /**
  29. * @dev See {IERC165-supportsInterface}.
  30. */
  31. function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC165) returns (bool) {
  32. return interfaceId == type(IERC2981).interfaceId || super.supportsInterface(interfaceId);
  33. }
  34. /**
  35. * @inheritdoc IERC2981
  36. */
  37. function royaltyInfo(uint256 _tokenId, uint256 _salePrice)
  38. external
  39. view
  40. virtual
  41. override
  42. returns (address, uint256)
  43. {
  44. RoyaltyInfo memory royalty = _tokenRoyaltyInfo[_tokenId];
  45. if (royalty.receiver == address(0)) {
  46. royalty = _defaultRoyaltyInfo;
  47. }
  48. uint256 royaltyAmount = (_salePrice * royalty.royaltyFraction) / _feeDenominator();
  49. return (royalty.receiver, royaltyAmount);
  50. }
  51. /**
  52. * @dev The denominator with which to interpret the fee set in {_setTokenRoyalty} and {_setDefaultRoyalty} as a
  53. * fraction of the sale price. Defaults to 10000 so fees are expressed in basis points, but may be customized by an
  54. * override.
  55. */
  56. function _feeDenominator() internal pure virtual returns (uint96) {
  57. return 10000;
  58. }
  59. /**
  60. * @dev Sets the royalty information that all ids in this contract will default to.
  61. *
  62. * Requirements:
  63. *
  64. * - `receiver` cannot be the zero address.
  65. * - `feeNumerator` cannot be greater than the fee denominator.
  66. */
  67. function _setDefaultRoyalty(address receiver, uint96 feeNumerator) internal virtual {
  68. require(feeNumerator <= _feeDenominator(), "ERC2981: royalty fee will exceed salePrice");
  69. require(receiver != address(0), "ERC2981: invalid receiver");
  70. _defaultRoyaltyInfo = RoyaltyInfo(receiver, feeNumerator);
  71. }
  72. /**
  73. * @dev Removes default royalty information.
  74. */
  75. function _deleteDefaultRoyalty() internal virtual {
  76. delete _defaultRoyaltyInfo;
  77. }
  78. /**
  79. * @dev Sets the royalty information for a specific token id, overriding the global default.
  80. *
  81. * Requirements:
  82. *
  83. * - `tokenId` must be already minted.
  84. * - `receiver` cannot be the zero address.
  85. * - `feeNumerator` cannot be greater than the fee denominator.
  86. */
  87. function _setTokenRoyalty(
  88. uint256 tokenId,
  89. address receiver,
  90. uint96 feeNumerator
  91. ) internal virtual {
  92. require(feeNumerator <= _feeDenominator(), "ERC2981: royalty fee will exceed salePrice");
  93. require(receiver != address(0), "ERC2981: Invalid parameters");
  94. _tokenRoyaltyInfo[tokenId] = RoyaltyInfo(receiver, feeNumerator);
  95. }
  96. /**
  97. * @dev Resets royalty information for the token id back to the global default.
  98. */
  99. function _resetTokenRoyalty(uint256 tokenId) internal virtual {
  100. delete _tokenRoyaltyInfo[tokenId];
  101. }
  102. }