forked from limitbreakinc/creator-token-standards
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathImmutableMinterRoyalties.sol
131 lines (106 loc) · 4.52 KB
/
ImmutableMinterRoyalties.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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
import "../access/OwnablePermissions.sol";
import "@openzeppelin/contracts/interfaces/IERC2981.sol";
import "@openzeppelin/contracts/utils/introspection/ERC165.sol";
/**
* @title ImmutableMinterRoyaltiesBase
* @author Limit Break, Inc.
* @dev Base functionality of an NFT mix-in contract implementing programmable royalties for minters
*/
abstract contract ImmutableMinterRoyaltiesBase is IERC2981, ERC165 {
error ImmutableMinterRoyalties__MinterCannotBeZeroAddress();
error ImmutableMinterRoyalties__MinterHasAlreadyBeenAssignedToTokenId();
error ImmutableMinterRoyalties__RoyaltyFeeWillExceedSalePrice();
uint256 public constant FEE_DENOMINATOR = 10_000;
uint256 private _royaltyFeeNumerator;
mapping (uint256 => address) private _minters;
/**
* @notice Indicates whether the contract implements the specified interface.
* @dev Overrides supportsInterface in ERC165.
* @param interfaceId The interface id
* @return true if the contract implements the specified interface, false otherwise
*/
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
return interfaceId == type(IERC2981).interfaceId || super.supportsInterface(interfaceId);
}
function royaltyFeeNumerator() public virtual view returns (uint256) {
return _royaltyFeeNumerator;
}
/**
* @notice Returns the royalty info for a given token ID and sale price.
* @dev Implements the IERC2981 interface.
* @param tokenId The token ID
* @param salePrice The sale price
* @return receiver The minter's address
* @return royaltyAmount The royalty amount
*/
function royaltyInfo(
uint256 tokenId,
uint256 salePrice
) external view override returns (address receiver, uint256 royaltyAmount) {
return (_minters[tokenId], (salePrice * royaltyFeeNumerator()) / FEE_DENOMINATOR);
}
/**
* @dev Internal function to be called when a new token is minted.
*
* @dev Throws when the minter is the zero address.
* @dev Throws when a minter has already been assigned to the specified token ID.
* @param minter The minter's address
* @param tokenId The token ID
*/
function _onMinted(address minter, uint256 tokenId) internal {
if (minter == address(0)) {
revert ImmutableMinterRoyalties__MinterCannotBeZeroAddress();
}
if (_minters[tokenId] != address(0)) {
revert ImmutableMinterRoyalties__MinterHasAlreadyBeenAssignedToTokenId();
}
_minters[tokenId] = minter;
}
/**
* @dev Internal function to be called when a token is burned. Clears the minter's address.
* @param tokenId The token ID
*/
function _onBurned(uint256 tokenId) internal {
delete _minters[tokenId];
}
function _setRoyaltyFeeNumerator(uint256 royaltyFeeNumerator_) internal {
if(royaltyFeeNumerator_ > FEE_DENOMINATOR) {
revert ImmutableMinterRoyalties__RoyaltyFeeWillExceedSalePrice();
}
_royaltyFeeNumerator = royaltyFeeNumerator_;
}
}
/**
* @title ImmutableMinterRoyalties
* @author Limit Break, Inc.
* @notice Constructable ImmutableMinterRoyalties Contract implementation.
*/
abstract contract ImmutableMinterRoyalties is ImmutableMinterRoyaltiesBase {
uint256 private immutable _royaltyFeeNumeratorImmutable;
constructor(uint256 royaltyFeeNumerator_) {
_setRoyaltyFeeNumerator(royaltyFeeNumerator_);
_royaltyFeeNumeratorImmutable = royaltyFeeNumerator_;
}
function royaltyFeeNumerator() public view override returns (uint256) {
return _royaltyFeeNumeratorImmutable;
}
}
/**
* @title ImmutableMinterRoyaltiesInitializable
* @author Limit Break, Inc.
* @notice Initializable ImmutableMinterRoyalties Contract implementation to allow for EIP-1167 clones.
*/
abstract contract ImmutableMinterRoyaltiesInitializable is OwnablePermissions, ImmutableMinterRoyaltiesBase {
error ImmutableMinterRoyaltiesInitializable__MinterRoyaltyFeeAlreadyInitialized();
bool private _minterRoyaltyFeeInitialized;
function initializeMinterRoyaltyFee(uint256 royaltyFeeNumerator_) public {
_requireCallerIsContractOwner();
if(_minterRoyaltyFeeInitialized) {
revert ImmutableMinterRoyaltiesInitializable__MinterRoyaltyFeeAlreadyInitialized();
}
_minterRoyaltyFeeInitialized = true;
_setRoyaltyFeeNumerator(royaltyFeeNumerator_);
}
}