You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
108 lines
4.0 KiB
Solidity
108 lines
4.0 KiB
Solidity
// SPDX-License-Identifier: MIT
|
|
// OpenZeppelin Contracts (last updated v4.7.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) public 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:
|
|
*
|
|
* - `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];
|
|
}
|
|
}
|