Skip to content

Commit ea32b38

Browse files
committed
ERC1155 tests pass
1 parent 82b8c59 commit ea32b38

File tree

5 files changed

+321
-10
lines changed

5 files changed

+321
-10
lines changed

remappings.txt

-1
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,3 @@ forge-std/=lib/forge-std/src/
55
@erc721a-upgradeable/=lib/ERC721A-Upgradeable/contracts/
66
@limitbreak/creator-token-standards/=lib/creator-token-standards/src/
77
@limitbreak/permit-c/=lib/PermitC/src/
8-
@imtbl/contracts/=lib/contracts.git/contracts/

src/module/token/immutable/ImmutableAllowlistERC1155.sol

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ contract ImmutableAllowlistERC1155 is
5151
config.fallbackFunctions[1] = FallbackFunction({selector: this.operatorAllowlist.selector, permissionBits: 0});
5252

5353
config.requiredInterfaces = new bytes4[](1);
54-
config.requiredInterfaces[0] = 0x80ac58cd; // ERC1155
54+
config.requiredInterfaces[0] = 0xd9b67a26; // ERC1155
5555

5656
config.registerInstallationCallback = true;
5757
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,320 @@
1+
// SPDX-License-Identifier: UNLICENSED
2+
pragma solidity ^0.8.20;
3+
4+
import "lib/forge-std/src/console.sol";
5+
6+
import {Test} from "forge-std/Test.sol";
7+
import {Role} from "src/Role.sol";
8+
9+
// Target contract
10+
11+
import {Module} from "src/Module.sol";
12+
import {ERC1155Core} from "src/core/token/ERC1155Core.sol";
13+
14+
import {ICore} from "src/interface/ICore.sol";
15+
import {IModuleConfig} from "src/interface/IModuleConfig.sol";
16+
import {ImmutableAllowlistERC1155} from "src/module/token/immutable/ImmutableAllowlistERC1155.sol";
17+
18+
import {OperatorAllowlistEnforced} from "dependecies/immutable/allowlist/OperatorAllowlistEnforced.sol";
19+
import {OperatorAllowlistEnforcementErrors} from "dependecies/immutable/errors/Errors.sol";
20+
import {OperatorAllowlist} from "dependecies/immutable/test/allowlist/OperatorAllowlist.sol";
21+
22+
contract Core is ERC1155Core {
23+
24+
constructor(
25+
string memory name,
26+
string memory symbol,
27+
string memory contractURI,
28+
address owner,
29+
address[] memory modules,
30+
bytes[] memory moduleInstallData
31+
) ERC1155Core(name, symbol, contractURI, owner, modules, moduleInstallData) {}
32+
33+
// disable mint, approve and tokenId callbacks for these tests
34+
function _beforeMint(address to, uint256 tokenId, uint256 value, bytes memory data) internal override {}
35+
36+
function _updateTokenId(uint256 tokenId) internal override returns (uint256) {
37+
return tokenId;
38+
}
39+
40+
}
41+
42+
contract DummyContract {
43+
44+
ERC1155Core public immutable erc1155Core;
45+
46+
constructor(address payable _erc1155Core) {
47+
erc1155Core = ERC1155Core(_erc1155Core);
48+
}
49+
50+
// Implement the IERC1155Receiver functions to accept ERC1155 tokens
51+
52+
function onERC1155Received(address operator, address from, uint256 id, uint256 value, bytes calldata data)
53+
external
54+
returns (bytes4)
55+
{
56+
return this.onERC1155Received.selector;
57+
}
58+
59+
function onERC1155BatchReceived(
60+
address operator,
61+
address from,
62+
uint256[] calldata ids,
63+
uint256[] calldata values,
64+
bytes calldata data
65+
) external returns (bytes4) {
66+
return this.onERC1155BatchReceived.selector;
67+
}
68+
69+
// Required to declare support for the ERC1155Receiver interface
70+
function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {
71+
return interfaceId == 0x4e2312e0;
72+
}
73+
74+
// Set approval for the operator to manage tokens
75+
function setApprovalForAll(address _operator) external {
76+
erc1155Core.setApprovalForAll(_operator, true);
77+
}
78+
79+
// Transfer a single token
80+
function transfer(address _to, uint256 _tokenId) external {
81+
erc1155Core.safeTransferFrom(address(this), _to, _tokenId, 1, "");
82+
}
83+
84+
// Batch transfer multiple tokens
85+
function batchTransfer(address _to, uint256[] calldata tokenIds, uint256[] calldata amounts) external {
86+
erc1155Core.safeBatchTransferFrom(address(this), _to, tokenIds, amounts, "");
87+
}
88+
89+
}
90+
91+
contract ImmutableAllowlistERC1155Test is Test {
92+
93+
Core public core;
94+
95+
ImmutableAllowlistERC1155 public immutableAllowlistModule;
96+
OperatorAllowlist public operatorAllowlist;
97+
DummyContract public dummyContract1;
98+
DummyContract public dummyContract2;
99+
100+
address public owner = address(0x1);
101+
address public actorOne = address(0x2);
102+
address public actorTwo = address(0x3);
103+
address public actorThree = address(0x4);
104+
105+
event OperatorAllowlistRegistryUpdated(address oldRegistry, address newRegistry);
106+
107+
function setUp() public {
108+
address[] memory modules;
109+
bytes[] memory moduleData;
110+
111+
core = new Core("test", "TEST", "", owner, modules, moduleData);
112+
immutableAllowlistModule = new ImmutableAllowlistERC1155();
113+
114+
vm.prank(owner);
115+
operatorAllowlist = new OperatorAllowlist(owner);
116+
117+
// install module
118+
vm.startPrank(owner);
119+
bytes memory encodedOperatorAllowlist =
120+
immutableAllowlistModule.encodeBytesOnInstall(address(operatorAllowlist));
121+
core.installModule(address(immutableAllowlistModule), encodedOperatorAllowlist);
122+
vm.stopPrank();
123+
124+
// set registrar role for owner
125+
vm.prank(owner);
126+
operatorAllowlist.grantRegistrarRole(owner);
127+
128+
// deploy dummy contract
129+
dummyContract1 = new DummyContract(payable(address(core)));
130+
dummyContract2 = new DummyContract(payable(address(core)));
131+
132+
// mint tokens
133+
core.mint(actorOne, 0, 1, string(""), ""); // tokenId 0
134+
core.mint(actorTwo, 1, 1, string(""), ""); // tokenId 1
135+
core.mint(actorThree, 3, 1, string(""), ""); // tokenId 2
136+
137+
vm.prank(owner);
138+
core.grantRoles(owner, Role._MANAGER_ROLE);
139+
}
140+
141+
function allowlist(address _target) internal {
142+
address[] memory allowlist = new address[](1);
143+
allowlist[0] = _target;
144+
vm.prank(owner);
145+
operatorAllowlist.addAddressToAllowlist(allowlist);
146+
}
147+
148+
/*///////////////////////////////////////////////////////////////
149+
Unit tests: `setOperatorAllowlistRegistry`
150+
//////////////////////////////////////////////////////////////*/
151+
152+
function test_state_setOperatorAllowlistRegistry() public {
153+
OperatorAllowlist operatorAllowlist2 = new OperatorAllowlist(owner);
154+
155+
vm.prank(owner);
156+
vm.expectEmit(true, true, true, true);
157+
emit OperatorAllowlistRegistryUpdated(address(operatorAllowlist), address(operatorAllowlist2));
158+
ImmutableAllowlistERC1155(address(core)).setOperatorAllowlistRegistry(address(operatorAllowlist2));
159+
160+
assertEq(ImmutableAllowlistERC1155(address(core)).operatorAllowlist(), address(operatorAllowlist2));
161+
}
162+
163+
function test_revert_setOperatorAllowlistRegistry() public {
164+
vm.prank(owner);
165+
// should revert since the allowlist does not implement the IOperatorAllowlist interface
166+
// and that it doesn't implement supportsInterface
167+
vm.expectRevert();
168+
ImmutableAllowlistERC1155(address(core)).setOperatorAllowlistRegistry(address(0x123));
169+
}
170+
171+
/*///////////////////////////////////////////////////////////////
172+
Unit tests: `beforeApproveForAll`
173+
//////////////////////////////////////////////////////////////*/
174+
175+
function test_state_beforeApproveForAllERC1155() public {
176+
// passes when msg.sender is an EOA and targetApproval is an EOA
177+
vm.prank(actorOne);
178+
core.setApprovalForAll(actorTwo, true);
179+
180+
// set allowlist for dummy contract
181+
address[] memory allowlist = new address[](3);
182+
allowlist[0] = address(dummyContract1);
183+
allowlist[1] = address(dummyContract2);
184+
allowlist[2] = address(actorThree);
185+
vm.prank(owner);
186+
operatorAllowlist.addAddressToAllowlist(allowlist);
187+
188+
vm.startPrank(actorThree);
189+
core.mint(actorThree, 3, 1, string(""), ""); // tokenId 3
190+
core.safeTransferFrom(actorThree, address(dummyContract1), 3, 1, "");
191+
vm.stopPrank();
192+
193+
// passes when msg.sender is a contract and is allowlisted
194+
// and when targetApproval is a contract and is allowlisted
195+
dummyContract1.setApprovalForAll(address(dummyContract2));
196+
}
197+
198+
function test_revert_beforeApproveForAllERC1155() public {
199+
vm.prank(actorOne);
200+
vm.expectRevert(
201+
abi.encodeWithSelector(
202+
OperatorAllowlistEnforcementErrors.ApproveTargetNotInAllowlist.selector, address(dummyContract1)
203+
)
204+
);
205+
core.setApprovalForAll(address(dummyContract1), true);
206+
}
207+
208+
/*///////////////////////////////////////////////////////////////
209+
Unit tests: `beforeTransferERC1155`
210+
//////////////////////////////////////////////////////////////*/
211+
212+
function test_state_beforeTransferERC1155() public {
213+
// set allowlist
214+
address[] memory allowlist = new address[](5);
215+
allowlist[0] = address(dummyContract1);
216+
allowlist[1] = address(dummyContract2);
217+
allowlist[2] = address(actorOne);
218+
allowlist[3] = address(actorTwo);
219+
allowlist[4] = address(actorThree);
220+
vm.prank(owner);
221+
operatorAllowlist.addAddressToAllowlist(allowlist);
222+
223+
vm.prank(actorOne);
224+
core.safeTransferFrom(actorOne, actorTwo, 0, 1, "");
225+
226+
// passes when msg.sender is an EOA and targetApproval is a contract and is allowlisted
227+
core.mint(actorThree, 3, 1, string(""), ""); // tokenId 3
228+
vm.startPrank(actorThree);
229+
core.safeTransferFrom(actorThree, address(dummyContract1), 3, 1, "");
230+
vm.stopPrank();
231+
232+
// passes when msg.sender is a contract and is allowlisted
233+
// and when targetApproval is a contract and is allowlisted
234+
dummyContract1.transfer(address(dummyContract2), 3);
235+
}
236+
237+
function test_revert_beforeTransferERC1155() public {
238+
// fails when msg.sender is not allowlisted
239+
vm.prank(actorOne);
240+
vm.expectRevert(
241+
abi.encodeWithSelector(OperatorAllowlistEnforcementErrors.CallerNotInAllowlist.selector, actorOne)
242+
);
243+
core.safeTransferFrom(actorOne, actorTwo, 0, 1, "");
244+
245+
// fails when target is not allowlisted
246+
allowlist(actorOne);
247+
vm.prank(actorOne);
248+
vm.expectRevert(
249+
abi.encodeWithSelector(
250+
OperatorAllowlistEnforcementErrors.TransferToNotInAllowlist.selector, address(dummyContract1)
251+
)
252+
);
253+
core.safeTransferFrom(actorOne, address(dummyContract1), 0, 1, "");
254+
}
255+
256+
/*///////////////////////////////////////////////////////////////
257+
Unit tests: `beforeTransferERC1155`
258+
//////////////////////////////////////////////////////////////*/
259+
260+
function test_state_beforeBatchTransferERC1155() public {
261+
// set allowlist
262+
address[] memory allowlist = new address[](5);
263+
allowlist[0] = address(dummyContract1);
264+
allowlist[1] = address(dummyContract2);
265+
allowlist[2] = address(actorOne);
266+
allowlist[3] = address(actorTwo);
267+
allowlist[4] = address(actorThree);
268+
vm.prank(owner);
269+
operatorAllowlist.addAddressToAllowlist(allowlist);
270+
271+
uint256[] memory tokenIds = new uint256[](1);
272+
tokenIds[0] = 0;
273+
uint256[] memory amounts = new uint256[](1);
274+
amounts[0] = 1;
275+
vm.prank(actorOne);
276+
core.safeBatchTransferFrom(actorOne, actorTwo, tokenIds, amounts, "");
277+
278+
// passes when msg.sender is an EOA and targetApproval is a contract and is allowlisted
279+
core.mint(actorThree, 3, 1, string(""), ""); // tokenId 3
280+
vm.startPrank(actorThree);
281+
core.safeTransferFrom(actorThree, address(dummyContract1), 3, 1, "");
282+
vm.stopPrank();
283+
284+
// passes when msg.sender is a contract and is allowlisted
285+
// and when targetApproval is a contract and is allowlisted
286+
uint256[] memory _tokenIds = new uint256[](1);
287+
tokenIds[0] = 3;
288+
uint256[] memory _amounts = new uint256[](1);
289+
amounts[0] = 1;
290+
dummyContract1.batchTransfer(address(dummyContract2), _tokenIds, _amounts);
291+
}
292+
293+
function test_revert_beforeBatchTransferERC1155() public {
294+
// fails when msg.sender is not allowlisted
295+
uint256[] memory tokenIds = new uint256[](1);
296+
tokenIds[0] = 0;
297+
uint256[] memory amounts = new uint256[](1);
298+
amounts[0] = 1;
299+
vm.prank(actorOne);
300+
vm.expectRevert(
301+
abi.encodeWithSelector(OperatorAllowlistEnforcementErrors.CallerNotInAllowlist.selector, actorOne)
302+
);
303+
core.safeBatchTransferFrom(actorOne, actorTwo, tokenIds, amounts, "");
304+
305+
// fails when target is not allowlisted
306+
uint256[] memory _tokenIds = new uint256[](1);
307+
tokenIds[0] = 3;
308+
uint256[] memory _amounts = new uint256[](1);
309+
amounts[0] = 1;
310+
allowlist(actorOne);
311+
vm.prank(actorOne);
312+
vm.expectRevert(
313+
abi.encodeWithSelector(
314+
OperatorAllowlistEnforcementErrors.TransferToNotInAllowlist.selector, address(dummyContract1)
315+
)
316+
);
317+
core.safeBatchTransferFrom(actorOne, address(dummyContract1), _tokenIds, _amounts, "");
318+
}
319+
320+
}

test/module/immutable/ImmutableAllowlistERC721.t.sol

-6
Original file line numberDiff line numberDiff line change
@@ -259,10 +259,4 @@ contract ImmutableAllowlistERC721Test is Test {
259259
core.transferFrom(actorOne, address(dummyContract1), 0);
260260
}
261261

262-
/// @notice Callback function for ERC721.setApprovalForAll
263-
function beforeApproveForAll(address _from, address _to, bool _approved) external returns (bytes memory) {}
264-
265-
/// @notice Callback function for ERC721.transferFrom/safeTransferFrom
266-
function beforeTransferERC721(address _from, address _to, uint256 _tokenId) external returns (bytes memory) {}
267-
268262
}

test/module/minting/ClaimableERC1155.t.sol

-2
Original file line numberDiff line numberDiff line change
@@ -293,8 +293,6 @@ contract ClaimableERC1155Test is Test {
293293
uid: bytes32("1")
294294
});
295295
bytes memory sig = signMintRequest(claimRequest, permissionedActorPrivateKey);
296-
console.log("permissoned actor address");
297-
console.logAddress(permissionedActor);
298296

299297
uint256 balBefore = tokenRecipient.balance;
300298
assertEq(balBefore, 100 ether);

0 commit comments

Comments
 (0)