/ test / CommunityERC721.t.sol
CommunityERC721.t.sol
  1  // SPDX-License-Identifier: UNLICENSED
  2  pragma solidity ^0.8.17;
  3  
  4  import { Test } from "forge-std/Test.sol";
  5  import { DeployOwnerAndMasterToken } from "../script/DeployOwnerAndMasterToken.s.sol";
  6  import { DeploymentConfig } from "../script/DeploymentConfig.s.sol";
  7  import { CommunityOwnable } from "../contracts/CommunityOwnable.sol";
  8  import { BaseToken } from "../contracts/tokens/BaseToken.sol";
  9  import { OwnerToken } from "../contracts/tokens/OwnerToken.sol";
 10  import { MasterToken } from "../contracts/tokens/MasterToken.sol";
 11  import { CommunityERC721 } from "../contracts/tokens/CommunityERC721.sol";
 12  
 13  contract CommunityERC721Test is Test {
 14      CommunityERC721 internal collectibleV1;
 15  
 16      address internal deployer;
 17      address[] internal accounts = new address[](4);
 18  
 19      string internal name = "Test";
 20      string internal symbol = "TEST";
 21      string internal baseURI = "http://local.dev";
 22      uint256 internal maxSupply = 4;
 23      bool internal remoteBurnable = true;
 24      bool internal transferable = true;
 25  
 26      function setUp() public virtual {
 27          DeployOwnerAndMasterToken deployment = new DeployOwnerAndMasterToken();
 28          (OwnerToken ownerToken, MasterToken masterToken, DeploymentConfig deploymentConfig) = deployment.run();
 29          deployer = deploymentConfig.deployer();
 30  
 31          collectibleV1 = new CommunityERC721(
 32              name, symbol, maxSupply, remoteBurnable, transferable, baseURI, address(ownerToken), address(masterToken)
 33          );
 34  
 35          accounts[0] = makeAddr("one");
 36          accounts[1] = makeAddr("two");
 37          accounts[2] = makeAddr("three");
 38          accounts[3] = makeAddr("four");
 39      }
 40  }
 41  
 42  contract DeploymentTest is CommunityERC721Test {
 43      function test_Deployment() public {
 44          assertEq(collectibleV1.name(), name);
 45          assertEq(collectibleV1.symbol(), symbol);
 46          assertEq(collectibleV1.maxSupply(), maxSupply);
 47          assertEq(collectibleV1.remoteBurnable(), remoteBurnable);
 48          assertEq(collectibleV1.transferable(), transferable);
 49          assertEq(collectibleV1.baseTokenURI(), baseURI);
 50      }
 51  }
 52  
 53  contract MintToTest is CommunityERC721Test {
 54      event StatusMint(address indexed from, address indexed to, uint256 indexed tokenId);
 55  
 56      function setUp() public virtual override {
 57          CommunityERC721Test.setUp();
 58      }
 59  
 60      function test_RevertWhen_SenderIsNotOwner() public {
 61          vm.expectRevert(CommunityOwnable.CommunityOwnable_NotAuthorized.selector);
 62          collectibleV1.mintTo(accounts);
 63      }
 64  
 65      function test_RevertWhen_MaxSupplyIsReached() public {
 66          vm.startPrank(deployer);
 67          collectibleV1.mintTo(accounts);
 68  
 69          address[] memory otherAddresses = new address[](1);
 70          otherAddresses[0] = makeAddr("anotherAccount");
 71          vm.expectRevert(BaseToken.BaseToken_MaxSupplyReached.selector);
 72          collectibleV1.mintTo(otherAddresses);
 73  
 74          assertEq(collectibleV1.maxSupply(), maxSupply);
 75          assertEq(collectibleV1.totalSupply(), maxSupply);
 76      }
 77  
 78      function test_MintTo() public {
 79          uint256 length = accounts.length;
 80          for (uint8 i = 0; i < length; i++) {
 81              assertEq(collectibleV1.balanceOf(accounts[i]), 0);
 82          }
 83          vm.prank(deployer);
 84          for (uint8 i = 0; i < length; i++) {
 85              vm.expectEmit(true, true, true, true);
 86              emit StatusMint(address(0), accounts[i], i);
 87          }
 88          collectibleV1.mintTo(accounts);
 89          for (uint8 i = 0; i < length; i++) {
 90              assertEq(collectibleV1.balanceOf(accounts[i]), 1);
 91          }
 92      }
 93  }
 94  
 95  contract RemoteBurnTest is CommunityERC721Test {
 96      function setUp() public virtual override {
 97          CommunityERC721Test.setUp();
 98      }
 99  
100      function test_RevertWhen_SenderIsNotOwner() public {
101          uint256[] memory ids = new uint256[](1);
102          ids[0] = 0;
103          vm.expectRevert(CommunityOwnable.CommunityOwnable_NotAuthorized.selector);
104          collectibleV1.remoteBurn(ids);
105      }
106  
107      function test_RemoteBurn() public {
108          vm.startPrank(deployer);
109          collectibleV1.mintTo(accounts);
110  
111          assertEq(collectibleV1.totalSupply(), maxSupply);
112  
113          uint256[] memory ids = new uint256[](1);
114          ids[0] = 0;
115          collectibleV1.remoteBurn(ids);
116  
117          assertEq(collectibleV1.balanceOf(accounts[0]), 0);
118          assertEq(collectibleV1.totalSupply(), maxSupply - 1);
119      }
120  }
121  
122  contract SafeBatchTransferFromTest is CommunityERC721Test {
123      function setUp() public virtual override {
124          CommunityERC721Test.setUp();
125      }
126  
127      function test_RevertWhen_ReceiversAndIdsMismatch() public {
128          // ensure sender owns a token
129          vm.prank(deployer);
130          collectibleV1.mintTo(accounts);
131  
132          address[] memory receivers = new address[](1);
133          receivers[0] = accounts[1];
134  
135          // ids must be of same length as `receivers`
136          uint256[] memory ids = new uint256[](2);
137          ids[0] = 0;
138          ids[1] = 1;
139  
140          vm.prank(accounts[0]);
141          vm.expectRevert(BaseToken.BaseToken_ReceiversAndIdsMismatch.selector);
142          collectibleV1.safeBatchTransferFrom(accounts[0], receivers, ids, "");
143      }
144  
145      function test_RevertWhen_NotAuthorized() public {
146          vm.prank(deployer);
147          collectibleV1.mintTo(accounts);
148  
149          address[] memory receivers = new address[](1);
150          receivers[0] = accounts[3];
151  
152          // ids must be of same length as `accounts`
153          uint256[] memory ids = new uint256[](1);
154          ids[0] = 0;
155  
156          // ensure accounts[3] has no ownership or approval of token with id `0`
157          assertEq(collectibleV1.ownerOf(ids[0]), accounts[0]);
158          assertEq(collectibleV1.isApprovedForAll(accounts[0], receivers[0]), false);
159  
160          vm.prank(receivers[0]);
161          vm.expectRevert(bytes("ERC721: caller is not token owner or approved"));
162          collectibleV1.safeBatchTransferFrom(accounts[0], receivers, ids, "");
163      }
164  
165      function test_RevertWhen_ReceiverAddressIsZero() public {
166          // ensure sender owns a token
167          vm.prank(deployer);
168          collectibleV1.mintTo(accounts);
169  
170          address[] memory receivers = new address[](1);
171          receivers[0] = address(0);
172  
173          uint256[] memory ids = new uint256[](1);
174          ids[0] = 0;
175  
176          vm.prank(accounts[0]);
177          vm.expectRevert(bytes("ERC721: transfer to the zero address"));
178          collectibleV1.safeBatchTransferFrom(accounts[0], receivers, ids, "");
179      }
180  
181      function test_SafeBatchTransferFrom() public {
182          // ensure sender owns a token
183          vm.prank(deployer);
184          address[] memory sameAddresses = new address[](3);
185          sameAddresses[0] = accounts[0];
186          sameAddresses[1] = accounts[0];
187          sameAddresses[2] = accounts[0];
188          collectibleV1.mintTo(sameAddresses);
189  
190          address[] memory receivers = new address[](3);
191          receivers[0] = accounts[1];
192          receivers[1] = accounts[2];
193          receivers[2] = accounts[3];
194  
195          uint256[] memory ids = new uint256[](3);
196          ids[0] = 0;
197          ids[1] = 1;
198          ids[2] = 2;
199  
200          vm.prank(accounts[0]);
201          collectibleV1.safeBatchTransferFrom(accounts[0], receivers, ids, "");
202  
203          assertEq(collectibleV1.balanceOf(accounts[0]), 0);
204          assertEq(collectibleV1.balanceOf(accounts[1]), 1);
205          assertEq(collectibleV1.balanceOf(accounts[2]), 1);
206          assertEq(collectibleV1.balanceOf(accounts[3]), 1);
207      }
208  
209      function test_SafeBatchTransferFromToSingleReceiver() public {
210          // ensure sender owns a token
211          vm.prank(deployer);
212          address[] memory sameAddresses = new address[](3);
213          sameAddresses[0] = accounts[0];
214          sameAddresses[1] = accounts[0];
215          sameAddresses[2] = accounts[0];
216          collectibleV1.mintTo(sameAddresses);
217  
218          address[] memory receivers = new address[](3);
219          receivers[0] = accounts[1];
220          receivers[1] = accounts[1];
221          receivers[2] = accounts[1];
222  
223          uint256[] memory ids = new uint256[](3);
224          ids[0] = 0;
225          ids[1] = 1;
226          ids[2] = 2;
227  
228          vm.prank(accounts[0]);
229          collectibleV1.safeBatchTransferFrom(accounts[0], receivers, ids, "");
230  
231          assertEq(collectibleV1.balanceOf(accounts[0]), 0);
232          assertEq(collectibleV1.balanceOf(accounts[1]), 3);
233      }
234  }
235  
236  contract NotTransferableTest is CommunityERC721Test {
237      function setUp() public virtual override {
238          DeployOwnerAndMasterToken deployment = new DeployOwnerAndMasterToken();
239          (OwnerToken ownerToken, MasterToken masterToken, DeploymentConfig deploymentConfig) = deployment.run();
240          deployer = deploymentConfig.deployer();
241  
242          collectibleV1 = new CommunityERC721(
243              name, symbol, maxSupply, remoteBurnable, false, baseURI, address(ownerToken), address(masterToken)
244          );
245  
246          accounts[0] = makeAddr("one");
247          accounts[1] = makeAddr("two");
248          accounts[2] = makeAddr("three");
249          accounts[3] = makeAddr("four");
250      }
251  
252      function test_RevertWhen_TokenIsNotTransferable() public {
253          // ensure accounts own tokens
254          vm.prank(deployer);
255          collectibleV1.mintTo(accounts);
256          uint256[] memory ids = new uint256[](4);
257          ids[0] = 0;
258          ids[1] = 1;
259          ids[2] = 2;
260          ids[3] = 3;
261  
262          vm.prank(accounts[0]);
263          vm.expectRevert(BaseToken.BaseToken_NotTransferable.selector);
264          collectibleV1.safeBatchTransferFrom(accounts[0], accounts, ids, "");
265      }
266  }