@croptop/core-v6 0.0.51 → 0.0.52
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +7 -7
- package/src/CTDeployer.sol +5 -2
- package/src/CTPublisher.sol +60 -11
- package/src/interfaces/ICTPublisher.sol +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@croptop/core-v6",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.52",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -29,12 +29,12 @@
|
|
|
29
29
|
"artifacts": "source ./.env && npx sphinx artifacts --org-id 'ea165b21-7cdc-4d7b-be59-ecdd4c26bee4' --project-name 'croptop-core-v6'"
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@bananapus/721-hook-v6": "^0.0.
|
|
33
|
-
"@bananapus/core-v6": "^0.0.
|
|
34
|
-
"@bananapus/ownable-v6": "^0.0.
|
|
35
|
-
"@bananapus/permission-ids-v6": "^0.0.
|
|
36
|
-
"@bananapus/router-terminal-v6": "^0.0.
|
|
37
|
-
"@bananapus/suckers-v6": "^0.0.
|
|
32
|
+
"@bananapus/721-hook-v6": "^0.0.54",
|
|
33
|
+
"@bananapus/core-v6": "^0.0.57",
|
|
34
|
+
"@bananapus/ownable-v6": "^0.0.27",
|
|
35
|
+
"@bananapus/permission-ids-v6": "^0.0.26",
|
|
36
|
+
"@bananapus/router-terminal-v6": "^0.0.46",
|
|
37
|
+
"@bananapus/suckers-v6": "^0.0.49",
|
|
38
38
|
"@openzeppelin/contracts": "5.6.1",
|
|
39
39
|
"@rev-net/core-v6": "^0.0.58"
|
|
40
40
|
},
|
package/src/CTDeployer.sol
CHANGED
|
@@ -257,8 +257,9 @@ contract CTDeployer is ERC2771Context, JBPermissioned, IJBRulesetDataHook, IERC7
|
|
|
257
257
|
}
|
|
258
258
|
}
|
|
259
259
|
|
|
260
|
-
// Transfer the project NFT to its intended owner.
|
|
261
|
-
|
|
260
|
+
// Transfer the project NFT to its intended owner. Use the safe path so contract owners must explicitly
|
|
261
|
+
// support receiving the project NFT before the launch can finalize.
|
|
262
|
+
PROJECTS.safeTransferFrom(address(this), owner, projectId);
|
|
262
263
|
|
|
263
264
|
// Give the initial project owner direct collection-control permissions while CTDeployer remains the hook's
|
|
264
265
|
// owner. This preserves the documented Croptop launch tradeoff: the owner can manage the collection directly
|
|
@@ -333,6 +334,8 @@ contract CTDeployer is ERC2771Context, JBPermissioned, IJBRulesetDataHook, IERC7
|
|
|
333
334
|
)
|
|
334
335
|
{
|
|
335
336
|
// If the cash out is from a sucker, return the full cash out amount without taxes or fees.
|
|
337
|
+
// Sucker cash-outs are the bridge accounting path: the value moving out of this chain must stay proportional
|
|
338
|
+
// to this chain's local backing. Do not add remote supply/surplus here.
|
|
336
339
|
if (SUCKER_REGISTRY.isSuckerOf({projectId: context.projectId, addr: context.holder})) {
|
|
337
340
|
return (0, context.cashOutCount, context.totalSupply, context.surplus.value, hookSpecifications);
|
|
338
341
|
}
|
package/src/CTPublisher.sol
CHANGED
|
@@ -145,8 +145,9 @@ contract CTPublisher is JBPermissioned, ERC2771Context, ICTPublisher {
|
|
|
145
145
|
revert CTPublisher_ZeroTotalSupply({hook: allowedPost.hook, category: allowedPost.category});
|
|
146
146
|
}
|
|
147
147
|
|
|
148
|
-
// Make sure the minimum supply does not surpass the maximum supply.
|
|
149
|
-
if (allowedPost.minimumTotalSupply > allowedPost.maximumTotalSupply)
|
|
148
|
+
// Make sure the minimum supply does not surpass the maximum supply. A max of 0 means unlimited.
|
|
149
|
+
if (allowedPost.maximumTotalSupply != 0 && allowedPost.minimumTotalSupply > allowedPost.maximumTotalSupply)
|
|
150
|
+
{
|
|
150
151
|
revert CTPublisher_MaxTotalSupplyLessThanMin({
|
|
151
152
|
min: allowedPost.minimumTotalSupply, max: allowedPost.maximumTotalSupply
|
|
152
153
|
});
|
|
@@ -380,8 +381,8 @@ contract CTPublisher is JBPermissioned, ERC2771Context, ICTPublisher {
|
|
|
380
381
|
/// @return minimumPrice The minimum price that a poster must pay to record a new NFT.
|
|
381
382
|
/// @return minimumTotalSupply The minimum total number of available tokens that a minter must set to record a new
|
|
382
383
|
/// NFT.
|
|
383
|
-
/// @return maximumTotalSupply The max total supply of NFTs that can be made available when minting.
|
|
384
|
-
///
|
|
384
|
+
/// @return maximumTotalSupply The max total supply of NFTs that can be made available when minting. 0 means
|
|
385
|
+
/// unlimited.
|
|
385
386
|
/// @return maximumSplitPercent The maximum split percent that a poster can set. 0 means splits are not allowed.
|
|
386
387
|
/// @return allowedAddresses The addresses allowed to post. Returns empty if all addresses are allowed.
|
|
387
388
|
function allowanceFor(
|
|
@@ -423,6 +424,10 @@ contract CTPublisher is JBPermissioned, ERC2771Context, ICTPublisher {
|
|
|
423
424
|
//*********************************************************************//
|
|
424
425
|
|
|
425
426
|
/// @notice Setup the posts.
|
|
427
|
+
/// @dev `adjustTiers` expects newly added tiers to be sorted by ascending category, while the pay metadata must
|
|
428
|
+
/// keep `tierIdsToMint` aligned with the caller's `posts` array so the requested NFTs are minted in the requested
|
|
429
|
+
/// order. `_setupPosts` therefore sorts only the tier configs and carries each config's original post index beside
|
|
430
|
+
/// it.
|
|
426
431
|
/// @param hook The NFT hook on which the posts will apply.
|
|
427
432
|
/// @param posts An array of posts that should be published as NFTs to the specified project.
|
|
428
433
|
/// @return tiersToAdd The tiers that will be created to represent the posts.
|
|
@@ -441,6 +446,10 @@ contract CTPublisher is JBPermissioned, ERC2771Context, ICTPublisher {
|
|
|
441
446
|
// Set the size of the tier IDs of the posts that should be minted once published.
|
|
442
447
|
tierIdsToMint = new uint256[](posts.length);
|
|
443
448
|
|
|
449
|
+
// Track which post produced each new tier. `tiersToAdd` may be sorted before it is sent to the 721 hook, but
|
|
450
|
+
// `tierIdsToMint` must stay indexed by the original `posts` array for the mint metadata below.
|
|
451
|
+
uint256[] memory newTierPostIndexes = new uint256[](posts.length);
|
|
452
|
+
|
|
444
453
|
// Keep a reference to the hook's store for tier lookups.
|
|
445
454
|
IJB721TiersHookStore store = hook.STORE();
|
|
446
455
|
|
|
@@ -532,8 +541,8 @@ contract CTPublisher is JBPermissioned, ERC2771Context, ICTPublisher {
|
|
|
532
541
|
}
|
|
533
542
|
|
|
534
543
|
// Make sure the total supply being made available for the post is at most the allowed maximum total
|
|
535
|
-
// supply.
|
|
536
|
-
if (post.totalSupply > maximumTotalSupply) {
|
|
544
|
+
// supply. A max of 0 means unlimited.
|
|
545
|
+
if (maximumTotalSupply != 0 && post.totalSupply > maximumTotalSupply) {
|
|
537
546
|
revert CTPublisher_TotalSupplyTooBig({
|
|
538
547
|
totalSupply: post.totalSupply, maximumTotalSupply: maximumTotalSupply
|
|
539
548
|
});
|
|
@@ -575,11 +584,8 @@ contract CTPublisher is JBPermissioned, ERC2771Context, ICTPublisher {
|
|
|
575
584
|
splits: post.splits
|
|
576
585
|
});
|
|
577
586
|
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
// Save the encodedIpfsUri as minted.
|
|
582
|
-
tierIdForEncodedIpfsUriOf[address(hook)][post.encodedIpfsUri] = tierIdsToMint[i];
|
|
587
|
+
newTierPostIndexes[numberOfTiersBeingAdded] = i;
|
|
588
|
+
numberOfTiersBeingAdded++;
|
|
583
589
|
|
|
584
590
|
// For new tiers, use the post's price for totalPrice accumulation.
|
|
585
591
|
totalPrice += post.price;
|
|
@@ -590,6 +596,49 @@ contract CTPublisher is JBPermissioned, ERC2771Context, ICTPublisher {
|
|
|
590
596
|
}
|
|
591
597
|
}
|
|
592
598
|
|
|
599
|
+
// The 721 store requires new tiers sorted by ascending category. This insertion sort normalizes caller input
|
|
600
|
+
// so multi-category publishes do not revert just because posts were supplied in mint order instead of category
|
|
601
|
+
// order. It is intentionally stable: equal-category posts stay in caller order because the loop only moves
|
|
602
|
+
// prior tiers with a strictly greater category.
|
|
603
|
+
for (uint256 i = 1; i < numberOfTiersBeingAdded;) {
|
|
604
|
+
// Keep the tier and its original post index together while shifting larger-category tiers to the right.
|
|
605
|
+
JB721TierConfig memory tierToSort = tiersToAdd[i];
|
|
606
|
+
uint256 postIndexToSort = newTierPostIndexes[i];
|
|
607
|
+
uint256 j = i;
|
|
608
|
+
|
|
609
|
+
while (j != 0 && tiersToAdd[j - 1].category > tierToSort.category) {
|
|
610
|
+
// Shift both arrays in lockstep; otherwise the tier ID assigned after sorting would be written back to
|
|
611
|
+
// the wrong post in `tierIdsToMint`.
|
|
612
|
+
tiersToAdd[j] = tiersToAdd[j - 1];
|
|
613
|
+
newTierPostIndexes[j] = newTierPostIndexes[j - 1];
|
|
614
|
+
|
|
615
|
+
unchecked {
|
|
616
|
+
--j;
|
|
617
|
+
}
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
// Insert the tier at its category-sorted position with the original post index still attached.
|
|
621
|
+
tiersToAdd[j] = tierToSort;
|
|
622
|
+
newTierPostIndexes[j] = postIndexToSort;
|
|
623
|
+
|
|
624
|
+
unchecked {
|
|
625
|
+
++i;
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
// Now that the store-facing tier order is final, translate each newly-created tier ID back into the caller's
|
|
630
|
+
// post order. The pay metadata expects this array to line up with `posts`, not with the sorted `tiersToAdd`.
|
|
631
|
+
for (uint256 i; i < numberOfTiersBeingAdded;) {
|
|
632
|
+
uint256 postIndex = newTierPostIndexes[i];
|
|
633
|
+
uint256 tierId = startingTierId + i;
|
|
634
|
+
tierIdsToMint[postIndex] = tierId;
|
|
635
|
+
tierIdForEncodedIpfsUriOf[address(hook)][posts[postIndex].encodedIpfsUri] = tierId;
|
|
636
|
+
|
|
637
|
+
unchecked {
|
|
638
|
+
++i;
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
|
|
593
642
|
// Resize the array if there's a mismatch in length.
|
|
594
643
|
if (numberOfTiersBeingAdded != posts.length) {
|
|
595
644
|
assembly ("memory-safe") {
|
|
@@ -40,7 +40,7 @@ interface ICTPublisher {
|
|
|
40
40
|
/// @param category The category for which this allowance applies.
|
|
41
41
|
/// @return minimumPrice The minimum price a poster must pay to publish a new NFT.
|
|
42
42
|
/// @return minimumTotalSupply The minimum total supply a poster must set for a new NFT.
|
|
43
|
-
/// @return maximumTotalSupply The maximum total supply allowed for a new NFT.
|
|
43
|
+
/// @return maximumTotalSupply The maximum total supply allowed for a new NFT. 0 means unlimited.
|
|
44
44
|
/// @return maximumSplitPercent The maximum split percent allowed for a new NFT.
|
|
45
45
|
/// @return allowedAddresses The addresses allowed to post. Empty if all addresses are allowed.
|
|
46
46
|
function allowanceFor(
|