-
Notifications
You must be signed in to change notification settings - Fork 11
/
ERC2981.sol
95 lines (78 loc) · 3.93 KB
/
ERC2981.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (token/common/ERC2981.sol)
pragma solidity ^0.8.0;
import '@openzeppelin/contracts/interfaces/IERC2981.sol';
import '@openzeppelin/contracts/utils/introspection/ERC165.sol';
// 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;
//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);
}
//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;
}
//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);
}
//Removes default royalty information.
function _deleteDefaultRoyalty() internal virtual {
delete _defaultRoyaltyInfo;
}
// 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);
}
// Resets royalty information for the token id back to the global default.
function _resetTokenRoyalty(uint256 tokenId) internal virtual {
delete _tokenRoyaltyInfo[tokenId];
}
}