Skip to content

Commit 9110f36

Browse files
committed
ERC721 tests pass
1 parent cb91a9f commit 9110f36

File tree

2 files changed

+161
-8
lines changed

2 files changed

+161
-8
lines changed

dependecies/immutable/test/allowlist/OperatorAllowlist.sol

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
pragma solidity ^0.8.24;
44

55
// Access Control
6-
76
import {Role} from "../../../../src/Role.sol";
87
import {OwnableRoles} from "@solady/auth/OwnableRoles.sol";
98

@@ -58,6 +57,7 @@ contract OperatorAllowlist is ERC165, OwnableRoles, IOperatorAllowlist {
5857
* @param admin the address to grant `Role._MANAGER_ROLE` to
5958
*/
6059
constructor(address admin) {
60+
_initializeOwner(admin);
6161
_grantRoles(admin, Role._MANAGER_ROLE);
6262
}
6363

test/module/immutable/ImmutableAllowlistERC721.t.sol

+160-7
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,36 @@ contract Core is ERC721Core {
3535

3636
}
3737

38-
contract TransferableERC721Test is Test {
38+
contract DummyContract {
39+
40+
ERC721Core public immutable erc721Core;
41+
42+
constructor(address payable _erc721Core) {
43+
erc721Core = ERC721Core(_erc721Core);
44+
}
45+
46+
function approve(address _to, uint256 _tokenId) external {
47+
erc721Core.approve(_to, _tokenId);
48+
}
49+
50+
function setApprovalForAll(address _operator) external {
51+
erc721Core.setApprovalForAll(_operator, true);
52+
}
53+
54+
function transfer(address _to, uint256 _tokenId) external {
55+
erc721Core.transferFrom(address(this), _to, _tokenId);
56+
}
57+
58+
}
59+
60+
contract ImmutableAllowlistERC721Test is Test {
3961

4062
Core public core;
4163

4264
ImmutableAllowlistERC721 public immutableAllowlistModule;
4365
OperatorAllowlist public operatorAllowlist;
66+
DummyContract public dummyContract1;
67+
DummyContract public dummyContract2;
4468

4569
address public owner = address(0x1);
4670
address public actorOne = address(0x2);
@@ -55,6 +79,8 @@ contract TransferableERC721Test is Test {
5579

5680
core = new Core("test", "TEST", "", owner, modules, moduleData);
5781
immutableAllowlistModule = new ImmutableAllowlistERC721();
82+
83+
vm.prank(owner);
5884
operatorAllowlist = new OperatorAllowlist(owner);
5985

6086
// install module
@@ -64,6 +90,14 @@ contract TransferableERC721Test is Test {
6490
core.installModule(address(immutableAllowlistModule), encodedOperatorAllowlist);
6591
vm.stopPrank();
6692

93+
// set registrar role for owner
94+
vm.prank(owner);
95+
operatorAllowlist.grantRegistrarRole(owner);
96+
97+
// deploy dummy contract
98+
dummyContract1 = new DummyContract(payable(address(core)));
99+
dummyContract2 = new DummyContract(payable(address(core)));
100+
67101
// mint tokens
68102
core.mint(actorOne, 1, string(""), ""); // tokenId 0
69103
core.mint(actorTwo, 1, string(""), ""); // tokenId 1
@@ -73,6 +107,13 @@ contract TransferableERC721Test is Test {
73107
core.grantRoles(owner, Role._MANAGER_ROLE);
74108
}
75109

110+
function allowlist(address _target) internal {
111+
address[] memory allowlist = new address[](1);
112+
allowlist[0] = _target;
113+
vm.prank(owner);
114+
operatorAllowlist.addAddressToAllowlist(allowlist);
115+
}
116+
76117
/*///////////////////////////////////////////////////////////////
77118
Unit tests: `setOperatorAllowlistRegistry`
78119
//////////////////////////////////////////////////////////////*/
@@ -97,14 +138,126 @@ contract TransferableERC721Test is Test {
97138
}
98139

99140
/*///////////////////////////////////////////////////////////////
100-
Unit tests: `setTransferable`
141+
Unit tests: `beforeApproveERC721`
101142
//////////////////////////////////////////////////////////////*/
102143

103-
/// @notice Callback function for ERC721.approve
104-
function beforeApproveERC721(address _from, address _to, uint256 _tokenId, bool _approve)
105-
external
106-
returns (bytes memory)
107-
{}
144+
function test_state_beforeApproveERC721() public {
145+
// passes when msg.sender is an EOA and targetApproval is an EOA
146+
vm.prank(actorOne);
147+
core.approve(actorTwo, 0);
148+
149+
// set allowlist for dummy contract
150+
address[] memory allowlist = new address[](3);
151+
allowlist[0] = address(dummyContract1);
152+
allowlist[1] = address(dummyContract2);
153+
allowlist[2] = address(actorThree);
154+
vm.prank(owner);
155+
operatorAllowlist.addAddressToAllowlist(allowlist);
156+
157+
vm.startPrank(actorThree);
158+
core.mint(actorThree, 2, string(""), ""); // tokenId 3
159+
core.transferFrom(actorThree, address(dummyContract1), 3);
160+
vm.stopPrank();
161+
162+
// passes when msg.sender is a contract and is allowlisted
163+
// and when targetApproval is a contract and is allowlisted
164+
dummyContract1.approve(address(dummyContract2), 3);
165+
}
166+
167+
function test_revert_beforeApproveERC721() public {
168+
vm.prank(actorOne);
169+
vm.expectRevert(
170+
abi.encodeWithSelector(
171+
OperatorAllowlistEnforcementErrors.ApproveTargetNotInAllowlist.selector, address(dummyContract1)
172+
)
173+
);
174+
core.approve(address(dummyContract1), 0);
175+
}
176+
177+
/*///////////////////////////////////////////////////////////////
178+
Unit tests: `beforeApproveForAll`
179+
//////////////////////////////////////////////////////////////*/
180+
181+
function test_state_beforeApproveForAllERC721() public {
182+
// passes when msg.sender is an EOA and targetApproval is an EOA
183+
vm.prank(actorOne);
184+
core.setApprovalForAll(actorTwo, true);
185+
186+
// set allowlist for dummy contract
187+
address[] memory allowlist = new address[](3);
188+
allowlist[0] = address(dummyContract1);
189+
allowlist[1] = address(dummyContract2);
190+
allowlist[2] = address(actorThree);
191+
vm.prank(owner);
192+
operatorAllowlist.addAddressToAllowlist(allowlist);
193+
194+
vm.startPrank(actorThree);
195+
core.mint(actorThree, 1, string(""), ""); // tokenId 3
196+
core.transferFrom(actorThree, address(dummyContract1), 3);
197+
vm.stopPrank();
198+
199+
// passes when msg.sender is a contract and is allowlisted
200+
// and when targetApproval is a contract and is allowlisted
201+
dummyContract1.setApprovalForAll(address(dummyContract2));
202+
}
203+
204+
function test_revert_beforeApproveForAllERC721() public {
205+
vm.prank(actorOne);
206+
vm.expectRevert(
207+
abi.encodeWithSelector(
208+
OperatorAllowlistEnforcementErrors.ApproveTargetNotInAllowlist.selector, address(dummyContract1)
209+
)
210+
);
211+
core.setApprovalForAll(address(dummyContract1), true);
212+
}
213+
214+
/*///////////////////////////////////////////////////////////////
215+
Unit tests: `beforeTransferERC721`
216+
//////////////////////////////////////////////////////////////*/
217+
218+
function test_state_beforeTransferERC721() public {
219+
// set allowlist
220+
address[] memory allowlist = new address[](5);
221+
allowlist[0] = address(dummyContract1);
222+
allowlist[1] = address(dummyContract2);
223+
allowlist[2] = address(actorOne);
224+
allowlist[3] = address(actorTwo);
225+
allowlist[4] = address(actorThree);
226+
vm.prank(owner);
227+
operatorAllowlist.addAddressToAllowlist(allowlist);
228+
229+
vm.prank(actorOne);
230+
core.transferFrom(actorOne, actorTwo, 0);
231+
232+
// passes when msg.sender is an EOA and targetApproval is a contract and is allowlisted
233+
core.mint(actorThree, 1, string(""), ""); // tokenId 3
234+
vm.startPrank(actorThree);
235+
core.transferFrom(actorThree, address(dummyContract1), 3);
236+
vm.stopPrank();
237+
238+
// passes when msg.sender is a contract and is allowlisted
239+
// and when targetApproval is a contract and is allowlisted
240+
dummyContract1.transfer(address(dummyContract2), 3);
241+
}
242+
243+
function test_revert_beforeTransferERC721() public {
244+
// fails when msg.sender is not allowlisted
245+
vm.prank(actorOne);
246+
vm.expectRevert(
247+
abi.encodeWithSelector(OperatorAllowlistEnforcementErrors.CallerNotInAllowlist.selector, actorOne)
248+
);
249+
core.transferFrom(actorOne, actorTwo, 0);
250+
251+
// fails when target is not allowlisted
252+
allowlist(actorOne);
253+
vm.prank(actorOne);
254+
vm.expectRevert(
255+
abi.encodeWithSelector(
256+
OperatorAllowlistEnforcementErrors.TransferToNotInAllowlist.selector, address(dummyContract1)
257+
)
258+
);
259+
core.transferFrom(actorOne, address(dummyContract1), 0);
260+
}
108261

109262
/// @notice Callback function for ERC721.setApprovalForAll
110263
function beforeApproveForAll(address _from, address _to, bool _approved) external returns (bytes memory) {}

0 commit comments

Comments
 (0)