@croptop/core-v6 0.0.42 → 0.0.43
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/README.md +2 -2
- package/package.json +9 -9
- package/references/runtime.md +1 -1
- package/src/CTDeployer.sol +23 -11
- package/src/CTPublisher.sol +32 -31
package/README.md
CHANGED
|
@@ -53,7 +53,7 @@ Many Croptop bugs are really deployment-shape bugs or posting-policy bugs, not g
|
|
|
53
53
|
1. `test/CTPublisher.t.sol`
|
|
54
54
|
2. `test/CTDeployer.t.sol`
|
|
55
55
|
3. `test/ClaimCollectionOwnership.t.sol`
|
|
56
|
-
4. `test/
|
|
56
|
+
4. `test/regression/FeeFallbackBlackhole.t.sol`
|
|
57
57
|
5. `test/regression/DuplicateUriFeeEvasion.t.sol`
|
|
58
58
|
|
|
59
59
|
## Integration Traps
|
|
@@ -105,7 +105,7 @@ src/
|
|
|
105
105
|
interfaces/
|
|
106
106
|
structs/
|
|
107
107
|
test/
|
|
108
|
-
publisher, deployer, fork, attack,
|
|
108
|
+
publisher, deployer, fork, attack, review, metadata, and regression coverage
|
|
109
109
|
script/
|
|
110
110
|
Deploy.s.sol
|
|
111
111
|
ConfigureFeeProject.s.sol
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@croptop/core-v6",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.43",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -29,17 +29,17 @@
|
|
|
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.24",
|
|
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.47",
|
|
33
|
+
"@bananapus/core-v6": "^0.0.44",
|
|
34
|
+
"@bananapus/ownable-v6": "^0.0.24",
|
|
35
|
+
"@bananapus/permission-ids-v6": "^0.0.23",
|
|
36
|
+
"@bananapus/router-terminal-v6": "^0.0.37",
|
|
37
|
+
"@bananapus/suckers-v6": "^0.0.37",
|
|
38
38
|
"@openzeppelin/contracts": "5.6.1",
|
|
39
|
-
"@rev-net/core-v6": "0.0.
|
|
39
|
+
"@rev-net/core-v6": "^0.0.45"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
|
-
"@bananapus/address-registry-v6": "0.0.25",
|
|
42
|
+
"@bananapus/address-registry-v6": "^0.0.25",
|
|
43
43
|
"@sphinx-labs/plugins": "0.33.3"
|
|
44
44
|
}
|
|
45
45
|
}
|
package/references/runtime.md
CHANGED
|
@@ -24,4 +24,4 @@
|
|
|
24
24
|
|
|
25
25
|
- [`test/CTPublisher.t.sol`](../test/CTPublisher.t.sol) and [`test/Test_MetadataGeneration.t.sol`](../test/Test_MetadataGeneration.t.sol) for content and metadata behavior.
|
|
26
26
|
- [`test/CTDeployer.t.sol`](../test/CTDeployer.t.sol) and [`test/Fork.t.sol`](../test/Fork.t.sol) for live deployment assumptions.
|
|
27
|
-
- [`test/CroptopAttacks.t.sol`](../test/CroptopAttacks.t.sol) and [`test/
|
|
27
|
+
- [`test/CroptopAttacks.t.sol`](../test/CroptopAttacks.t.sol) and [`test/TestRegressionGaps.sol`](../test/TestRegressionGaps.sol) when the issue could be in publisher or deployer behavior rather than one isolated function.
|
package/src/CTDeployer.sol
CHANGED
|
@@ -120,7 +120,8 @@ contract CTDeployer is ERC2771Context, JBPermissioned, IJBRulesetDataHook, IERC7
|
|
|
120
120
|
|
|
121
121
|
/// @notice Claim ownership of the collection.
|
|
122
122
|
/// @dev Two-step ownership transfer process:
|
|
123
|
-
/// Step 1 (this function):
|
|
123
|
+
/// Step 1 (this function): Revokes the deployer-scoped permissions granted at launch, then transfers hook
|
|
124
|
+
/// ownership to the project via `transferOwnershipToProject()`.
|
|
124
125
|
/// After this call, `hook.owner()` resolves dynamically through `PROJECTS.ownerOf(projectId)`.
|
|
125
126
|
/// Step 2 (caller must do separately): The project owner grants CTPublisher the `ADJUST_721_TIERS` permission
|
|
126
127
|
/// for the project so that `mintFrom()` continues to work.
|
|
@@ -132,11 +133,29 @@ contract CTDeployer is ERC2771Context, JBPermissioned, IJBRulesetDataHook, IERC7
|
|
|
132
133
|
// Get the project ID of the hook.
|
|
133
134
|
uint256 projectId = hook.PROJECT_ID();
|
|
134
135
|
|
|
136
|
+
// Keep a reference to the caller.
|
|
137
|
+
address caller = _msgSender();
|
|
138
|
+
|
|
135
139
|
// Make sure the caller is the owner of the project.
|
|
136
|
-
if (PROJECTS.ownerOf(projectId) !=
|
|
137
|
-
revert CTDeployer_NotOwnerOfProject({projectId: projectId, hook: address(hook), caller:
|
|
140
|
+
if (PROJECTS.ownerOf(projectId) != caller) {
|
|
141
|
+
revert CTDeployer_NotOwnerOfProject({projectId: projectId, hook: address(hook), caller: caller});
|
|
138
142
|
}
|
|
139
143
|
|
|
144
|
+
// Revoke the deployer-scoped permissions that were granted to the caller during deployment.
|
|
145
|
+
// These permissions (ADJUST_721_TIERS, SET_721_METADATA, MINT_721, SET_721_DISCOUNT_PERCENT) allowed the
|
|
146
|
+
// project owner to manage the hook while the deployer owned it. After transferring hook ownership to the
|
|
147
|
+
// project, these deployer-scoped grants are no longer needed and should be cleaned up to prevent stale
|
|
148
|
+
// permission leakage.
|
|
149
|
+
PERMISSIONS.setPermissionsFor({
|
|
150
|
+
account: address(this),
|
|
151
|
+
permissionsData: JBPermissionsData({
|
|
152
|
+
operator: caller,
|
|
153
|
+
// forge-lint: disable-next-line(unsafe-typecast)
|
|
154
|
+
projectId: uint64(projectId),
|
|
155
|
+
permissionIds: new uint8[](0)
|
|
156
|
+
})
|
|
157
|
+
});
|
|
158
|
+
|
|
140
159
|
// Transfer the hook's ownership to the project.
|
|
141
160
|
JBOwnable(address(hook)).transferOwnershipToProject(projectId);
|
|
142
161
|
}
|
|
@@ -171,7 +190,6 @@ contract CTDeployer is ERC2771Context, JBPermissioned, IJBRulesetDataHook, IERC7
|
|
|
171
190
|
projectId = PROJECTS.createFor(address(this));
|
|
172
191
|
|
|
173
192
|
// Deploy a blank project.
|
|
174
|
-
// slither-disable-next-line reentrancy-benign
|
|
175
193
|
hook = DEPLOYER.deployHookFor({
|
|
176
194
|
projectId: projectId,
|
|
177
195
|
deployTiersHookConfig: JBDeploy721TiersHookConfig({
|
|
@@ -200,7 +218,6 @@ contract CTDeployer is ERC2771Context, JBPermissioned, IJBRulesetDataHook, IERC7
|
|
|
200
218
|
rulesetConfigurations[0].metadata.useDataHookForCashOut = true;
|
|
201
219
|
|
|
202
220
|
// Launch the rulesets for the reserved project.
|
|
203
|
-
// slither-disable-next-line unused-return
|
|
204
221
|
controller.launchRulesetsFor({
|
|
205
222
|
projectId: projectId,
|
|
206
223
|
projectUri: projectConfig.projectUri,
|
|
@@ -214,7 +231,7 @@ contract CTDeployer is ERC2771Context, JBPermissioned, IJBRulesetDataHook, IERC7
|
|
|
214
231
|
|
|
215
232
|
// Configure allowed posts.
|
|
216
233
|
if (projectConfig.allowedPosts.length > 0) {
|
|
217
|
-
_configurePostingCriteriaFor(address(hook), projectConfig.allowedPosts);
|
|
234
|
+
_configurePostingCriteriaFor({hook: address(hook), allowedPosts: projectConfig.allowedPosts});
|
|
218
235
|
}
|
|
219
236
|
|
|
220
237
|
// Deploy the suckers (if applicable).
|
|
@@ -226,7 +243,6 @@ contract CTDeployer is ERC2771Context, JBPermissioned, IJBRulesetDataHook, IERC7
|
|
|
226
243
|
|
|
227
244
|
// Successful deployments are discoverable from the registry, and failures are reported without reverting
|
|
228
245
|
// the project launch.
|
|
229
|
-
// slither-disable-next-line unused-return
|
|
230
246
|
try SUCKER_REGISTRY.deploySuckersFor({
|
|
231
247
|
projectId: projectId,
|
|
232
248
|
salt: suckerSalt,
|
|
@@ -237,7 +253,6 @@ contract CTDeployer is ERC2771Context, JBPermissioned, IJBRulesetDataHook, IERC7
|
|
|
237
253
|
// no-op
|
|
238
254
|
}
|
|
239
255
|
catch (bytes memory reason) {
|
|
240
|
-
// slither-disable-next-line reentrancy-events
|
|
241
256
|
emit CTDeployer_SuckerDeploymentFailed({projectId: projectId, salt: suckerSalt, reason: reason});
|
|
242
257
|
}
|
|
243
258
|
}
|
|
@@ -283,7 +298,6 @@ contract CTDeployer is ERC2771Context, JBPermissioned, IJBRulesetDataHook, IERC7
|
|
|
283
298
|
|
|
284
299
|
// Deploy the suckers. The sucker registry performs its own permission check against this forwarding helper,
|
|
285
300
|
// so an unapproved CTDeployer fails at the downstream registry boundary without an extra preflight read here.
|
|
286
|
-
// slither-disable-next-line unused-return
|
|
287
301
|
suckers = SUCKER_REGISTRY.deploySuckersFor({
|
|
288
302
|
projectId: projectId,
|
|
289
303
|
salt: keccak256(abi.encode(suckerDeploymentConfiguration.salt, _msgSender())),
|
|
@@ -334,7 +348,6 @@ contract CTDeployer is ERC2771Context, JBPermissioned, IJBRulesetDataHook, IERC7
|
|
|
334
348
|
hookSpecifications
|
|
335
349
|
);
|
|
336
350
|
}
|
|
337
|
-
// slither-disable-next-line unused-return
|
|
338
351
|
return hook.beforeCashOutRecordedWith(context);
|
|
339
352
|
}
|
|
340
353
|
|
|
@@ -358,7 +371,6 @@ contract CTDeployer is ERC2771Context, JBPermissioned, IJBRulesetDataHook, IERC7
|
|
|
358
371
|
return (context.weight, hookSpecifications);
|
|
359
372
|
}
|
|
360
373
|
|
|
361
|
-
// slither-disable-next-line unused-return
|
|
362
374
|
return hook.beforePayRecordedWith(context);
|
|
363
375
|
}
|
|
364
376
|
|
package/src/CTPublisher.sol
CHANGED
|
@@ -32,19 +32,20 @@ contract CTPublisher is JBPermissioned, ERC2771Context, ICTPublisher {
|
|
|
32
32
|
//*********************************************************************//
|
|
33
33
|
|
|
34
34
|
error CTPublisher_DuplicatePost(bytes32 encodedIPFSUri);
|
|
35
|
-
error CTPublisher_EmptyEncodedIPFSUri();
|
|
35
|
+
error CTPublisher_EmptyEncodedIPFSUri(uint256 postIndex);
|
|
36
36
|
error CTPublisher_InsufficientEthSent(uint256 expected, uint256 sent);
|
|
37
37
|
error CTPublisher_MaxTotalSupplyLessThanMin(uint256 min, uint256 max);
|
|
38
38
|
error CTPublisher_NotInAllowList(address addr, address[] allowedAddresses);
|
|
39
39
|
error CTPublisher_PriceTooSmall(uint256 price, uint256 minimumPrice);
|
|
40
|
-
error CTPublisher_DuplicatePayMetadata();
|
|
40
|
+
error CTPublisher_DuplicatePayMetadata(bytes4 payMetadataId);
|
|
41
41
|
error CTPublisher_FeePaymentFailed(uint256 feeAmount);
|
|
42
42
|
error CTPublisher_SplitPercentExceedsMaximum(uint256 splitPercent, uint256 maximumSplitPercent);
|
|
43
43
|
error CTPublisher_TotalSupplyTooBig(uint256 totalSupply, uint256 maximumTotalSupply);
|
|
44
44
|
error CTPublisher_TotalSupplyTooSmall(uint256 totalSupply, uint256 minimumTotalSupply);
|
|
45
|
-
error CTPublisher_NoPosts();
|
|
46
|
-
error
|
|
47
|
-
error
|
|
45
|
+
error CTPublisher_NoPosts(address caller);
|
|
46
|
+
error CTPublisher_InvalidFeeBeneficiary();
|
|
47
|
+
error CTPublisher_UnauthorizedToPostInCategory(address hook, uint24 category);
|
|
48
|
+
error CTPublisher_ZeroTotalSupply(address hook, uint24 category);
|
|
48
49
|
|
|
49
50
|
//*********************************************************************//
|
|
50
51
|
// ------------------------- public constants ------------------------ //
|
|
@@ -133,7 +134,6 @@ contract CTPublisher is JBPermissioned, ERC2771Context, ICTPublisher {
|
|
|
133
134
|
emit ConfigurePostingCriteria({hook: allowedPost.hook, allowedPost: allowedPost, caller: _msgSender()});
|
|
134
135
|
|
|
135
136
|
// Enforce permissions.
|
|
136
|
-
// slither-disable-next-line reentrancy-events,calls-loop
|
|
137
137
|
_requirePermissionFrom({
|
|
138
138
|
account: JBOwnable(allowedPost.hook).owner(),
|
|
139
139
|
projectId: IJB721TiersHook(allowedPost.hook).PROJECT_ID(),
|
|
@@ -142,14 +142,14 @@ contract CTPublisher is JBPermissioned, ERC2771Context, ICTPublisher {
|
|
|
142
142
|
|
|
143
143
|
// Make sure there is a minimum supply.
|
|
144
144
|
if (allowedPost.minimumTotalSupply == 0) {
|
|
145
|
-
revert CTPublisher_ZeroTotalSupply();
|
|
145
|
+
revert CTPublisher_ZeroTotalSupply({hook: allowedPost.hook, category: allowedPost.category});
|
|
146
146
|
}
|
|
147
147
|
|
|
148
148
|
// Make sure the minimum supply does not surpass the maximum supply.
|
|
149
149
|
if (allowedPost.minimumTotalSupply > allowedPost.maximumTotalSupply) {
|
|
150
|
-
revert CTPublisher_MaxTotalSupplyLessThanMin(
|
|
151
|
-
allowedPost.minimumTotalSupply, allowedPost.maximumTotalSupply
|
|
152
|
-
);
|
|
150
|
+
revert CTPublisher_MaxTotalSupplyLessThanMin({
|
|
151
|
+
min: allowedPost.minimumTotalSupply, max: allowedPost.maximumTotalSupply
|
|
152
|
+
});
|
|
153
153
|
}
|
|
154
154
|
|
|
155
155
|
uint256 packed;
|
|
@@ -202,7 +202,10 @@ contract CTPublisher is JBPermissioned, ERC2771Context, ICTPublisher {
|
|
|
202
202
|
override
|
|
203
203
|
{
|
|
204
204
|
// Reject empty posts to prevent fee-free metadata shadowing.
|
|
205
|
-
if (posts.length == 0) revert CTPublisher_NoPosts();
|
|
205
|
+
if (posts.length == 0) revert CTPublisher_NoPosts(_msgSender());
|
|
206
|
+
|
|
207
|
+
// Reject address(0) as fee beneficiary to prevent burning fee project tokens.
|
|
208
|
+
if (feeBeneficiary == address(0)) revert CTPublisher_InvalidFeeBeneficiary();
|
|
206
209
|
|
|
207
210
|
// Keep a reference to the amount being paid, which is msg.value minus the fee.
|
|
208
211
|
uint256 payValue = msg.value;
|
|
@@ -216,7 +219,7 @@ contract CTPublisher is JBPermissioned, ERC2771Context, ICTPublisher {
|
|
|
216
219
|
{
|
|
217
220
|
// Setup the posts.
|
|
218
221
|
(JB721TierConfig[] memory tiersToAdd, uint256[] memory tierIdsToMint, uint256 totalPrice) =
|
|
219
|
-
_setupPosts(hook, posts);
|
|
222
|
+
_setupPosts({hook: hook, posts: posts});
|
|
220
223
|
|
|
221
224
|
if (projectId != FEE_PROJECT_ID) {
|
|
222
225
|
// Keep a reference to the fee that will be paid.
|
|
@@ -227,7 +230,7 @@ contract CTPublisher is JBPermissioned, ERC2771Context, ICTPublisher {
|
|
|
227
230
|
|
|
228
231
|
// Make sure enough ETH was sent to cover the fee.
|
|
229
232
|
if (payValue < fee) {
|
|
230
|
-
revert CTPublisher_InsufficientEthSent(totalPrice + fee, msg.value);
|
|
233
|
+
revert CTPublisher_InsufficientEthSent({expected: totalPrice + fee, sent: msg.value});
|
|
231
234
|
}
|
|
232
235
|
|
|
233
236
|
payValue -= fee;
|
|
@@ -235,11 +238,10 @@ contract CTPublisher is JBPermissioned, ERC2771Context, ICTPublisher {
|
|
|
235
238
|
|
|
236
239
|
// Make sure the amount sent to this function is at least the specified price of the tier plus the fee.
|
|
237
240
|
if (totalPrice > payValue) {
|
|
238
|
-
revert CTPublisher_InsufficientEthSent(totalPrice, msg.value);
|
|
241
|
+
revert CTPublisher_InsufficientEthSent({expected: totalPrice, sent: msg.value});
|
|
239
242
|
}
|
|
240
243
|
|
|
241
244
|
// Add the new tiers.
|
|
242
|
-
// slither-disable-next-line reentrancy-events
|
|
243
245
|
hook.adjustTiers({tiersToAdd: tiersToAdd, tierIdsToRemove: new uint256[](0)});
|
|
244
246
|
|
|
245
247
|
// Keep a reference to the metadata ID target.
|
|
@@ -249,9 +251,8 @@ contract CTPublisher is JBPermissioned, ERC2771Context, ICTPublisher {
|
|
|
249
251
|
// tier selection, allowing the caller to mint arbitrary tiers.
|
|
250
252
|
{
|
|
251
253
|
bytes4 payId = JBMetadataResolver.getId({purpose: "pay", target: metadataIdTarget});
|
|
252
|
-
// slither-disable-next-line unused-return
|
|
253
254
|
(bool exists,) = JBMetadataResolver.getDataFor({id: payId, metadata: additionalPayMetadata});
|
|
254
|
-
if (exists) revert CTPublisher_DuplicatePayMetadata();
|
|
255
|
+
if (exists) revert CTPublisher_DuplicatePayMetadata(payId);
|
|
255
256
|
}
|
|
256
257
|
|
|
257
258
|
// Create the metadata for the payment to specify the tier IDs that should be minted. We create manually the
|
|
@@ -288,7 +289,6 @@ contract CTPublisher is JBPermissioned, ERC2771Context, ICTPublisher {
|
|
|
288
289
|
DIRECTORY.primaryTerminalOf({projectId: projectId, token: JBConstants.NATIVE_TOKEN});
|
|
289
290
|
|
|
290
291
|
// Make the payment.
|
|
291
|
-
// slither-disable-next-line unused-return
|
|
292
292
|
projectTerminal.pay{value: payValue}({
|
|
293
293
|
projectId: projectId,
|
|
294
294
|
token: JBConstants.NATIVE_TOKEN,
|
|
@@ -312,7 +312,6 @@ contract CTPublisher is JBPermissioned, ERC2771Context, ICTPublisher {
|
|
|
312
312
|
|
|
313
313
|
// Make the fee payment. If the fee sink is unavailable, refund the fee to the caller
|
|
314
314
|
// rather than trapping or silently redirecting protocol funds.
|
|
315
|
-
// slither-disable-next-line unused-return
|
|
316
315
|
try feeTerminal.pay{value: payValue}({
|
|
317
316
|
projectId: FEE_PROJECT_ID,
|
|
318
317
|
amount: payValue,
|
|
@@ -323,7 +322,6 @@ contract CTPublisher is JBPermissioned, ERC2771Context, ICTPublisher {
|
|
|
323
322
|
metadata: ""
|
|
324
323
|
}) {}
|
|
325
324
|
catch {
|
|
326
|
-
// slither-disable-next-line low-level-calls
|
|
327
325
|
(bool success,) = _msgSender().call{value: payValue}("");
|
|
328
326
|
if (!success) revert CTPublisher_FeePaymentFailed(payValue);
|
|
329
327
|
}
|
|
@@ -363,7 +361,6 @@ contract CTPublisher is JBPermissioned, ERC2771Context, ICTPublisher {
|
|
|
363
361
|
|
|
364
362
|
// If there's a tier ID stored, resolve it.
|
|
365
363
|
if (tierId != 0) {
|
|
366
|
-
// slither-disable-next-line calls-loop
|
|
367
364
|
tiers[i] = IJB721TiersHook(hook).STORE().tierOf({hook: hook, id: tierId, includeResolvedUri: false});
|
|
368
365
|
}
|
|
369
366
|
|
|
@@ -463,13 +460,13 @@ contract CTPublisher is JBPermissioned, ERC2771Context, ICTPublisher {
|
|
|
463
460
|
// Make sure the post includes an encodedIPFSUri.
|
|
464
461
|
// forge-lint: disable-next-line(unsafe-typecast)
|
|
465
462
|
if (post.encodedIPFSUri == bytes32("")) {
|
|
466
|
-
revert CTPublisher_EmptyEncodedIPFSUri();
|
|
463
|
+
revert CTPublisher_EmptyEncodedIPFSUri({postIndex: i});
|
|
467
464
|
}
|
|
468
465
|
|
|
469
466
|
// Check for duplicate encodedIPFSUri within the same batch to prevent fee evasion.
|
|
470
467
|
for (uint256 j; j < i;) {
|
|
471
468
|
if (posts[j].encodedIPFSUri == post.encodedIPFSUri) {
|
|
472
|
-
revert CTPublisher_DuplicatePost(post.encodedIPFSUri);
|
|
469
|
+
revert CTPublisher_DuplicatePost({encodedIPFSUri: post.encodedIPFSUri});
|
|
473
470
|
}
|
|
474
471
|
unchecked {
|
|
475
472
|
++j;
|
|
@@ -486,10 +483,8 @@ contract CTPublisher is JBPermissioned, ERC2771Context, ICTPublisher {
|
|
|
486
483
|
// The cache can become stale if the tier was removed (via adjustTiers) or
|
|
487
484
|
// its URI was changed (via setMetadata). In either case, clear the stale
|
|
488
485
|
// mapping and fall through to create a new tier.
|
|
489
|
-
// slither-disable-next-line calls-loop
|
|
490
486
|
JB721Tier memory cachedTier =
|
|
491
487
|
store.tierOf({hook: address(hook), id: tierId, includeResolvedUri: false});
|
|
492
|
-
// slither-disable-next-line calls-loop
|
|
493
488
|
if (store.isTierRemoved(address(hook), tierId) || cachedTier.encodedIPFSUri != post.encodedIPFSUri)
|
|
494
489
|
{
|
|
495
490
|
delete tierIdForEncodedIPFSUriOf[address(hook)][post.encodedIPFSUri];
|
|
@@ -518,34 +513,40 @@ contract CTPublisher is JBPermissioned, ERC2771Context, ICTPublisher {
|
|
|
518
513
|
|
|
519
514
|
// Make sure the category being posted to allows publishing.
|
|
520
515
|
if (minimumTotalSupply == 0) {
|
|
521
|
-
revert CTPublisher_UnauthorizedToPostInCategory();
|
|
516
|
+
revert CTPublisher_UnauthorizedToPostInCategory({hook: address(hook), category: post.category});
|
|
522
517
|
}
|
|
523
518
|
|
|
524
519
|
// Make sure the price being paid for the post is at least the allowed minimum price.
|
|
525
520
|
if (post.price < minimumPrice) {
|
|
526
|
-
revert CTPublisher_PriceTooSmall(post.price, minimumPrice);
|
|
521
|
+
revert CTPublisher_PriceTooSmall({price: post.price, minimumPrice: minimumPrice});
|
|
527
522
|
}
|
|
528
523
|
|
|
529
524
|
// Make sure the total supply being made available for the post is at least the allowed minimum
|
|
530
525
|
// total supply.
|
|
531
526
|
if (post.totalSupply < minimumTotalSupply) {
|
|
532
|
-
revert CTPublisher_TotalSupplyTooSmall(
|
|
527
|
+
revert CTPublisher_TotalSupplyTooSmall({
|
|
528
|
+
totalSupply: post.totalSupply, minimumTotalSupply: minimumTotalSupply
|
|
529
|
+
});
|
|
533
530
|
}
|
|
534
531
|
|
|
535
532
|
// Make sure the total supply being made available for the post is at most the allowed maximum total
|
|
536
533
|
// supply.
|
|
537
534
|
if (post.totalSupply > maximumTotalSupply) {
|
|
538
|
-
revert CTPublisher_TotalSupplyTooBig(
|
|
535
|
+
revert CTPublisher_TotalSupplyTooBig({
|
|
536
|
+
totalSupply: post.totalSupply, maximumTotalSupply: maximumTotalSupply
|
|
537
|
+
});
|
|
539
538
|
}
|
|
540
539
|
|
|
541
540
|
// Make sure the split percent is within the allowed maximum.
|
|
542
541
|
if (post.splitPercent > maximumSplitPercent) {
|
|
543
|
-
revert CTPublisher_SplitPercentExceedsMaximum(
|
|
542
|
+
revert CTPublisher_SplitPercentExceedsMaximum({
|
|
543
|
+
splitPercent: post.splitPercent, maximumSplitPercent: maximumSplitPercent
|
|
544
|
+
});
|
|
544
545
|
}
|
|
545
546
|
|
|
546
547
|
// Make sure the address is allowed to post.
|
|
547
548
|
if (addresses.length != 0 && !_isAllowed({addrs: _msgSender(), addresses: addresses})) {
|
|
548
|
-
revert CTPublisher_NotInAllowList(_msgSender(), addresses);
|
|
549
|
+
revert CTPublisher_NotInAllowList({addr: _msgSender(), allowedAddresses: addresses});
|
|
549
550
|
}
|
|
550
551
|
}
|
|
551
552
|
|