@@ -15,8 +15,10 @@ function toSingleton(address account) pure returns (address[] memory) {
15
15
16
16
contract ERC721ConsecutiveTarget is StdUtils , ERC721Consecutive {
17
17
uint256 public totalMinted = 0 ;
18
+ uint96 public firstConsecutiveId = 0 ;
18
19
19
- constructor (address [] memory receivers , uint256 [] memory batches ) ERC721 ("" , "" ) {
20
+ constructor (address [] memory receivers , uint256 [] memory batches , uint96 startingId ) ERC721 ("" , "" ) {
21
+ firstConsecutiveId = startingId;
20
22
for (uint256 i = 0 ; i < batches.length ; i++ ) {
21
23
address receiver = receivers[i % receivers.length ];
22
24
uint96 batchSize = uint96 (bound (batches[i], 0 , _maxBatchSize ()));
@@ -28,36 +30,43 @@ contract ERC721ConsecutiveTarget is StdUtils, ERC721Consecutive {
28
30
function burn (uint256 tokenId ) public {
29
31
_burn (tokenId);
30
32
}
33
+
34
+ function _firstConsecutiveId () internal view virtual override returns (uint96 ) {
35
+ return firstConsecutiveId;
36
+ }
31
37
}
32
38
33
39
contract ERC721ConsecutiveTest is Test {
34
- function test_balance (address receiver , uint256 [] calldata batches ) public {
40
+ function test_balance (address receiver , uint256 [] calldata batches , uint96 startingId ) public {
35
41
vm.assume (receiver != address (0 ));
42
+ vm.assume (startingId < type (uint96 ).max - 5000 );
36
43
37
- ERC721ConsecutiveTarget token = new ERC721ConsecutiveTarget (toSingleton (receiver), batches);
44
+ ERC721ConsecutiveTarget token = new ERC721ConsecutiveTarget (toSingleton (receiver), batches, startingId );
38
45
39
46
assertEq (token.balanceOf (receiver), token.totalMinted ());
40
47
}
41
48
42
- function test_ownership (address receiver , uint256 [] calldata batches , uint256 [2 ] calldata unboundedTokenId ) public {
49
+ function test_ownership (address receiver , uint256 [] calldata batches , uint256 [2 ] calldata unboundedTokenId , uint96 startingId ) public {
43
50
vm.assume (receiver != address (0 ));
51
+ vm.assume (startingId < type (uint96 ).max - 5000 );
44
52
45
- ERC721ConsecutiveTarget token = new ERC721ConsecutiveTarget (toSingleton (receiver), batches);
53
+ ERC721ConsecutiveTarget token = new ERC721ConsecutiveTarget (toSingleton (receiver), batches, startingId );
46
54
47
55
if (token.totalMinted () > 0 ) {
48
- uint256 validTokenId = bound (unboundedTokenId[0 ], 0 , token.totalMinted () - 1 );
56
+ uint256 validTokenId = bound (unboundedTokenId[0 ], startingId, startingId + token.totalMinted () - 1 );
49
57
assertEq (token.ownerOf (validTokenId), receiver);
50
58
}
51
59
52
- uint256 invalidTokenId = bound (unboundedTokenId[1 ], token.totalMinted (), type ( uint256 ).max );
60
+ uint256 invalidTokenId = bound (unboundedTokenId[1 ], startingId + token.totalMinted (), startingId + token. totalMinted () + 1 );
53
61
vm.expectRevert ();
54
62
token.ownerOf (invalidTokenId);
55
63
}
56
64
57
- function test_burn (address receiver , uint256 [] calldata batches , uint256 unboundedTokenId ) public {
65
+ function test_burn (address receiver , uint256 [] calldata batches , uint256 unboundedTokenId , uint96 startingId ) public {
58
66
vm.assume (receiver != address (0 ));
67
+ vm.assume (startingId < type (uint96 ).max - 5000 );
59
68
60
- ERC721ConsecutiveTarget token = new ERC721ConsecutiveTarget (toSingleton (receiver), batches);
69
+ ERC721ConsecutiveTarget token = new ERC721ConsecutiveTarget (toSingleton (receiver), batches, startingId );
61
70
62
71
// only test if we minted at least one token
63
72
uint256 supply = token.totalMinted ();
@@ -93,7 +102,7 @@ contract ERC721ConsecutiveTest is Test {
93
102
batches[0 ] = bound (unboundedBatches[0 ], 1 , 5000 );
94
103
batches[1 ] = bound (unboundedBatches[1 ], 1 , 5000 );
95
104
96
- ERC721ConsecutiveTarget token = new ERC721ConsecutiveTarget (receivers, batches);
105
+ ERC721ConsecutiveTarget token = new ERC721ConsecutiveTarget (receivers, batches, 0 );
97
106
98
107
uint256 tokenId0 = bound (unboundedTokenId[0 ], 0 , batches[0 ] - 1 );
99
108
uint256 tokenId1 = bound (unboundedTokenId[1 ], 0 , batches[1 ] - 1 ) + batches[0 ];
@@ -119,4 +128,28 @@ contract ERC721ConsecutiveTest is Test {
119
128
assertEq (token.balanceOf (accounts[0 ]), batches[0 ]);
120
129
assertEq (token.balanceOf (accounts[1 ]), batches[1 ]);
121
130
}
131
+
132
+ function test_start_consecutive_id (
133
+ address receiver ,
134
+ uint256 [2 ] calldata unboundedBatches ,
135
+ uint256 [2 ] calldata unboundedTokenId ,
136
+ uint96 startingId
137
+ ) public {
138
+ vm.assume (receiver != address (0 ));
139
+ uint256 startingTokenId = bound (startingId, 1 , 5000 );
140
+
141
+ // We assume _maxBatchSize is 5000 (the default). This test will break otherwise.
142
+ uint256 [] memory batches = new uint256 [](2 );
143
+ batches[0 ] = bound (unboundedBatches[0 ], startingTokenId, 5000 );
144
+ batches[1 ] = bound (unboundedBatches[1 ], startingTokenId, 5000 );
145
+
146
+ ERC721ConsecutiveTarget token = new ERC721ConsecutiveTarget (toSingleton (receiver), batches, uint96 (startingTokenId));
147
+
148
+ uint256 tokenId0 = bound (unboundedTokenId[0 ], startingTokenId, batches[0 ]);
149
+ uint256 tokenId1 = bound (unboundedTokenId[1 ], startingTokenId, batches[1 ]);
150
+
151
+ assertEq (token.ownerOf (tokenId0), receiver);
152
+ assertEq (token.ownerOf (tokenId1), receiver);
153
+ assertEq (token.balanceOf (receiver), batches[0 ] + batches[1 ]);
154
+ }
122
155
}
0 commit comments