123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118 |
- // SPDX-License-Identifier: MIT
- // OpenZeppelin Contracts (last updated v4.5.0) (token/common/ERC2981.sol)
- pragma solidity ^0.8.0;
- import "../../interfaces/IERC2981.sol";
- import "../../utils/introspection/ERC165.sol";
- /**
- * @dev Implementation of the NFT Royalty Standard, a standardized way to retrieve royalty payment information.
- *
- * Royalty information can be specified globally for all token ids via {_setDefaultRoyalty}, and/or individually for
- * specific token ids via {_setTokenRoyalty}. The latter takes precedence over the first.
- *
- * Royalty is specified as a fraction of sale price. {_feeDenominator} is overridable but defaults to 10000, meaning the
- * fee is specified in basis points by default.
- *
- * IMPORTANT: ERC-2981 only specifies a way to signal royalty information and does not enforce its payment. See
- * https://eips.ethereum.org/EIPS/eip-2981#optional-royalty-payments[Rationale] in the EIP. Marketplaces are expected to
- * voluntarily pay royalties together with sales, but note that this standard is not yet widely supported.
- *
- * _Available since v4.5._
- */
- abstract contract ERC2981 is IERC2981, ERC165 {
- struct RoyaltyInfo {
- address receiver;
- uint96 royaltyFraction;
- }
- RoyaltyInfo private _defaultRoyaltyInfo;
- mapping(uint256 => RoyaltyInfo) private _tokenRoyaltyInfo;
- /**
- * @dev See {IERC165-supportsInterface}.
- */
- function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC165) returns (bool) {
- return interfaceId == type(IERC2981).interfaceId || super.supportsInterface(interfaceId);
- }
- /**
- * @inheritdoc IERC2981
- */
- function royaltyInfo(uint256 _tokenId, uint256 _salePrice)
- external
- view
- virtual
- override
- returns (address, uint256)
- {
- RoyaltyInfo memory royalty = _tokenRoyaltyInfo[_tokenId];
- if (royalty.receiver == address(0)) {
- royalty = _defaultRoyaltyInfo;
- }
- uint256 royaltyAmount = (_salePrice * royalty.royaltyFraction) / _feeDenominator();
- return (royalty.receiver, royaltyAmount);
- }
- /**
- * @dev The denominator with which to interpret the fee set in {_setTokenRoyalty} and {_setDefaultRoyalty} as a
- * fraction of the sale price. Defaults to 10000 so fees are expressed in basis points, but may be customized by an
- * override.
- */
- function _feeDenominator() internal pure virtual returns (uint96) {
- return 10000;
- }
- /**
- * @dev Sets the royalty information that all ids in this contract will default to.
- *
- * Requirements:
- *
- * - `receiver` cannot be the zero address.
- * - `feeNumerator` cannot be greater than the fee denominator.
- */
- function _setDefaultRoyalty(address receiver, uint96 feeNumerator) internal virtual {
- require(feeNumerator <= _feeDenominator(), "ERC2981: royalty fee will exceed salePrice");
- require(receiver != address(0), "ERC2981: invalid receiver");
- _defaultRoyaltyInfo = RoyaltyInfo(receiver, feeNumerator);
- }
- /**
- * @dev Removes default royalty information.
- */
- function _deleteDefaultRoyalty() internal virtual {
- delete _defaultRoyaltyInfo;
- }
- /**
- * @dev Sets the royalty information for a specific token id, overriding the global default.
- *
- * Requirements:
- *
- * - `tokenId` must be already minted.
- * - `receiver` cannot be the zero address.
- * - `feeNumerator` cannot be greater than the fee denominator.
- */
- function _setTokenRoyalty(
- uint256 tokenId,
- address receiver,
- uint96 feeNumerator
- ) internal virtual {
- require(feeNumerator <= _feeDenominator(), "ERC2981: royalty fee will exceed salePrice");
- require(receiver != address(0), "ERC2981: Invalid parameters");
- _tokenRoyaltyInfo[tokenId] = RoyaltyInfo(receiver, feeNumerator);
- }
- /**
- * @dev Resets royalty information for the token id back to the global default.
- */
- function _resetTokenRoyalty(uint256 tokenId) internal virtual {
- delete _tokenRoyaltyInfo[tokenId];
- }
- }
|