Skip to content

Commit cb75021

Browse files
authored
[feature] hybrid erc721 (#58)
* [feature] hybrid erc721 * [feature] add burn check and batch transfer * [chore] tests * [chore] inheritance shenanigans
1 parent 8df2e4a commit cb75021

19 files changed

+2130
-101
lines changed

contracts/errors/Errors.sol

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,30 @@ interface IImmutableERC721Errors {
99

1010
/// @dev Caller tried to mint an already burned token
1111
error IImmutableERC721MismatchedTransferLengths();
12+
13+
/// @dev Caller tried to mint a tokenid that is above the hybrid threshold
14+
error IImmutableERC721IDAboveThreshold(uint256 tokenId);
15+
16+
/// @dev Caller is not approved or owner
17+
error IImmutableERC721NotOwnerOrOperator(uint256 tokenId);
1218
}
1319

1420
interface RoyaltyEnforcementErrors {
1521
/// @dev Caller tried to mint an already burned token
1622
error RoyaltyEnforcementDoesNotImplementRequiredInterface();
23+
24+
/// @dev Error thrown when calling address is not Allowlisted
25+
error CallerNotInAllowlist(address caller);
26+
27+
/// @dev Error thrown when 'from' address is not Allowlisted
28+
error TransferFromNotInAllowlist(address from);
29+
30+
/// @dev Error thrown when 'to' address is not Allowlisted
31+
error TransferToNotInAllowlist(address to);
32+
33+
/// @dev Error thrown when approve target is not Allowlisted
34+
error ApproveTargetNotInAllowlist(address target);
35+
36+
/// @dev Error thrown when approve target is not Allowlisted
37+
error ApproverNotInAllowlist(address approver);
1738
}

contracts/royalty-enforcement/RoyaltyEnforced.sol

Lines changed: 40 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -14,23 +14,6 @@ abstract contract RoyaltyEnforced is
1414
AccessControlEnumerable,
1515
RoyaltyEnforcementErrors
1616
{
17-
/// ===== Errors =====
18-
19-
/// @dev Error thrown when calling address is not Allowlisted
20-
error CallerNotInAllowlist(address caller);
21-
22-
/// @dev Error thrown when 'from' address is not Allowlisted
23-
error TransferFromNotInAllowlist(address from);
24-
25-
/// @dev Error thrown when 'to' address is not Allowlisted
26-
error TransferToNotInAllowlist(address to);
27-
28-
/// @dev Error thrown when approve target is not Allowlisted
29-
error ApproveTargetNotInAllowlist(address target);
30-
31-
/// @dev Error thrown when approve target is not Allowlisted
32-
error ApproverNotInAllowlist(address approver);
33-
3417
/// ===== Events =====
3518

3619
/// @dev Emitted whenever the transfer Allowlist registry is updated
@@ -76,60 +59,52 @@ abstract contract RoyaltyEnforced is
7659
}
7760

7861
modifier validateApproval(address targetApproval) {
79-
// Only check if the registry is set
80-
if (address(royaltyAllowlist) != address(0)) {
81-
// Check for:
82-
// 1. approver is an EOA. Contract constructor is handled as transfers 'from' are blocked
83-
// 2. approver is address or bytecode is allowlisted
84-
if (
85-
msg.sender.code.length != 0 &&
86-
!royaltyAllowlist.isAllowlisted(msg.sender)
87-
) {
88-
revert ApproverNotInAllowlist(msg.sender);
89-
}
90-
91-
// Check for:
92-
// 1. approval target is an EOA
93-
// 2. approval target address is Allowlisted or target address bytecode is Allowlisted
94-
if (
95-
targetApproval.code.length != 0 &&
96-
!royaltyAllowlist.isAllowlisted(targetApproval)
97-
) {
98-
revert ApproveTargetNotInAllowlist(targetApproval);
99-
}
62+
// Check for:
63+
// 1. approver is an EOA. Contract constructor is handled as transfers 'from' are blocked
64+
// 2. approver is address or bytecode is allowlisted
65+
if (
66+
msg.sender.code.length != 0 &&
67+
!royaltyAllowlist.isAllowlisted(msg.sender)
68+
) {
69+
revert ApproverNotInAllowlist(msg.sender);
70+
}
71+
72+
// Check for:
73+
// 1. approval target is an EOA
74+
// 2. approval target address is Allowlisted or target address bytecode is Allowlisted
75+
if (
76+
targetApproval.code.length != 0 &&
77+
!royaltyAllowlist.isAllowlisted(targetApproval)
78+
) {
79+
revert ApproveTargetNotInAllowlist(targetApproval);
10080
}
10181
_;
10282
}
10383

10484
/// @dev Internal function to validate whether the calling address is an EOA or Allowlisted
10585
modifier validateTransfer(address from, address to) {
106-
// Only check if the registry is set
107-
if (address(royaltyAllowlist) != address(0)) {
108-
// Check for:
109-
// 1. caller is an EOA
110-
// 2. caller is Allowlisted or is the calling address bytecode is Allowlisted
111-
if (
112-
msg.sender != tx.origin &&
113-
!royaltyAllowlist.isAllowlisted(msg.sender)
114-
) {
115-
revert CallerNotInAllowlist(msg.sender);
116-
}
117-
118-
// Check for:
119-
// 1. from is an EOA
120-
// 2. from is Allowlisted or from address bytecode is Allowlisted
121-
if (
122-
from.code.length != 0 && !royaltyAllowlist.isAllowlisted(from)
123-
) {
124-
revert TransferFromNotInAllowlist(from);
125-
}
126-
127-
// Check for:
128-
// 1. to is an EOA
129-
// 2. to is Allowlisted or to address bytecode is Allowlisted
130-
if (to.code.length != 0 && !royaltyAllowlist.isAllowlisted(to)) {
131-
revert TransferToNotInAllowlist(to);
132-
}
86+
// Check for:
87+
// 1. caller is an EOA
88+
// 2. caller is Allowlisted or is the calling address bytecode is Allowlisted
89+
if (
90+
msg.sender != tx.origin &&
91+
!royaltyAllowlist.isAllowlisted(msg.sender)
92+
) {
93+
revert CallerNotInAllowlist(msg.sender);
94+
}
95+
96+
// Check for:
97+
// 1. from is an EOA
98+
// 2. from is Allowlisted or from address bytecode is Allowlisted
99+
if (from.code.length != 0 && !royaltyAllowlist.isAllowlisted(from)) {
100+
revert TransferFromNotInAllowlist(from);
101+
}
102+
103+
// Check for:
104+
// 1. to is an EOA
105+
// 2. to is Allowlisted or to address bytecode is Allowlisted
106+
if (to.code.length != 0 && !royaltyAllowlist.isAllowlisted(to)) {
107+
revert TransferToNotInAllowlist(to);
133108
}
134109
_;
135110
}

0 commit comments

Comments
 (0)