Skip to content

Commit 345bc15

Browse files
committed
Forking over immutable OperatorAllowlistEnforced contract
1 parent 0b34bf3 commit 345bc15

3 files changed

Lines changed: 177 additions & 0 deletions

File tree

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// Copyright Immutable Pty Ltd 2018 - 2023
2+
// SPDX-License-Identifier: Apache 2.0
3+
pragma solidity ^0.8.24;
4+
5+
/**
6+
* @notice Required interface of an OperatorAllowlist compliant contract
7+
*/
8+
interface IOperatorAllowlist {
9+
/**
10+
* @notice Returns true if an address is Allowlisted false otherwise
11+
* @param target the address to be checked against the Allowlist
12+
*/
13+
function isAllowlisted(address target) external view returns (bool);
14+
}
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
// Copyright Immutable Pty Ltd 2018 - 2023
2+
// SPDX-License-Identifier: Apache 2.0
3+
// slither-disable-start calls-loop
4+
pragma solidity ^0.8.24;
5+
6+
// Allowlist Registry
7+
import {IOperatorAllowlist} from "./IOperatorAllowlist.sol";
8+
9+
// Errors
10+
import {OperatorAllowlistEnforcementErrors} from "../errors/Errors.sol";
11+
12+
interface IERC165 {
13+
14+
function supportsInterface(bytes4 interfaceId) external view returns (bool);
15+
16+
}
17+
18+
/*
19+
OperatorAllowlistEnforced is an abstract contract that token contracts can inherit in order to set the
20+
address of the OperatorAllowlist registry that it will interface with, so that the token contract may
21+
enable the restriction of approvals and transfers to allowlisted users.
22+
OperatorAllowlistEnforced is not designed to be upgradeable or extended.
23+
*/
24+
25+
abstract contract OperatorAllowlistEnforced is OperatorAllowlistEnforcementErrors {
26+
27+
/// ===== Events =====
28+
29+
/// @notice Emitted whenever the transfer Allowlist registry is updated
30+
event OperatorAllowlistRegistryUpdated(address oldRegistry, address newRegistry);
31+
32+
/// ===== Modifiers =====
33+
34+
/**
35+
* @notice Internal function to validate an approval, according to whether the target is an EOA or Allowlisted
36+
* @param targetApproval the address of the approval target to be validated
37+
*/
38+
modifier validateApproval(address targetApproval) {
39+
// Check for:
40+
// 1. approver is an EOA. Contract constructor is handled as transfers 'from' are blocked
41+
// 2. approver is address or bytecode is allowlisted
42+
if (msg.sender.code.length != 0 && !operatorAllowlist.isAllowlisted(msg.sender)) {
43+
revert ApproverNotInAllowlist(msg.sender);
44+
}
45+
46+
// Check for:
47+
// 1. approval target is an EOA
48+
// 2. approval target address is Allowlisted or target address bytecode is Allowlisted
49+
if (targetApproval.code.length != 0 && !operatorAllowlist.isAllowlisted(targetApproval)) {
50+
revert ApproveTargetNotInAllowlist(targetApproval);
51+
}
52+
_;
53+
}
54+
55+
/**
56+
* @notice Internal function to validate a transfer, according to whether the calling address,
57+
* from address and to address is an EOA or Allowlisted
58+
* @param from the address of the from target to be validated
59+
* @param to the address of the to target to be validated
60+
*/
61+
modifier validateTransfer(address from, address to) {
62+
// Check for:
63+
// 1. caller is an EOA
64+
// 2. caller is Allowlisted or is the calling address bytecode is Allowlisted
65+
if (
66+
msg.sender != tx.origin // solhint-disable-line avoid-tx-origin
67+
&& !operatorAllowlist.isAllowlisted(msg.sender)
68+
) {
69+
revert CallerNotInAllowlist(msg.sender);
70+
}
71+
72+
// Check for:
73+
// 1. from is an EOA
74+
// 2. from is Allowlisted or from address bytecode is Allowlisted
75+
if (from.code.length != 0 && !operatorAllowlist.isAllowlisted(from)) {
76+
revert TransferFromNotInAllowlist(from);
77+
}
78+
79+
// Check for:
80+
// 1. to is an EOA
81+
// 2. to is Allowlisted or to address bytecode is Allowlisted
82+
if (to.code.length != 0 && !operatorAllowlist.isAllowlisted(to)) {
83+
revert TransferToNotInAllowlist(to);
84+
}
85+
_;
86+
}
87+
88+
/// ===== External functions =====
89+
90+
/**
91+
* @notice Internal function to set the operator allowlist the calling contract will interface with
92+
* @param _operatorAllowlist the address of the Allowlist registry
93+
*/
94+
function _setOperatorAllowlistRegistry(address _operatorAllowlist) internal {
95+
if (!IERC165(_operatorAllowlist).supportsInterface(type(IOperatorAllowlist).interfaceId)) {
96+
revert AllowlistDoesNotImplementIOperatorAllowlist();
97+
}
98+
99+
emit OperatorAllowlistRegistryUpdated(address(operatorAllowlist), _operatorAllowlist);
100+
operatorAllowlist = IOperatorAllowlist(_operatorAllowlist);
101+
}
102+
103+
}
104+
// slither-disable-end calls-loop
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
//SPDX-License-Identifier: Apache 2.0
2+
pragma solidity ^0.8.24;
3+
4+
interface IImmutableERC721Errors {
5+
/// @dev Caller tried to mint an already burned token
6+
error IImmutableERC721TokenAlreadyBurned(uint256 tokenId);
7+
8+
/// @dev Caller tried to mint an already burned token
9+
error IImmutableERC721SendingToZerothAddress();
10+
11+
/// @dev Caller tried to mint an already burned token
12+
error IImmutableERC721MismatchedTransferLengths();
13+
14+
/// @dev Caller tried to mint a tokenid that is above the hybrid threshold
15+
error IImmutableERC721IDAboveThreshold(uint256 tokenId);
16+
17+
/// @dev Caller is not approved or owner
18+
error IImmutableERC721NotOwnerOrOperator(uint256 tokenId);
19+
20+
/// @dev Current token owner is not what was expected
21+
error IImmutableERC721MismatchedTokenOwner(uint256 tokenId, address currentOwner);
22+
23+
/// @dev Signer is zeroth address
24+
error SignerCannotBeZerothAddress();
25+
26+
/// @dev Deadline exceeded for permit
27+
error PermitExpired();
28+
29+
/// @dev Derived signature is invalid (EIP721 and EIP1271)
30+
error InvalidSignature();
31+
}
32+
33+
interface OperatorAllowlistEnforcementErrors {
34+
/// @dev Error thrown when the operatorAllowlist address does not implement the IOperatorAllowlist interface
35+
error AllowlistDoesNotImplementIOperatorAllowlist();
36+
37+
/// @dev Error thrown when calling address is not OperatorAllowlist
38+
error CallerNotInAllowlist(address caller);
39+
40+
/// @dev Error thrown when 'from' address is not OperatorAllowlist
41+
error TransferFromNotInAllowlist(address from);
42+
43+
/// @dev Error thrown when 'to' address is not OperatorAllowlist
44+
error TransferToNotInAllowlist(address to);
45+
46+
/// @dev Error thrown when approve target is not OperatorAllowlist
47+
error ApproveTargetNotInAllowlist(address target);
48+
49+
/// @dev Error thrown when approve target is not OperatorAllowlist
50+
error ApproverNotInAllowlist(address approver);
51+
}
52+
53+
interface IImmutableERC1155Errors {
54+
/// @dev Deadline exceeded for permit
55+
error PermitExpired();
56+
57+
/// @dev Derived signature is invalid (EIP721 and EIP1271)
58+
error InvalidSignature();
59+
}

0 commit comments

Comments
 (0)