@croptop/core-v6 0.0.35 → 0.0.36
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
CHANGED
package/src/CTPublisher.sol
CHANGED
|
@@ -37,6 +37,7 @@ contract CTPublisher is JBPermissioned, ERC2771Context, ICTPublisher {
|
|
|
37
37
|
error CTPublisher_SplitPercentExceedsMaximum(uint256 splitPercent, uint256 maximumSplitPercent);
|
|
38
38
|
error CTPublisher_TotalSupplyTooBig(uint256 totalSupply, uint256 maximumTotalSupply);
|
|
39
39
|
error CTPublisher_TotalSupplyTooSmall(uint256 totalSupply, uint256 minimumTotalSupply);
|
|
40
|
+
error CTPublisher_NoPosts();
|
|
40
41
|
error CTPublisher_UnauthorizedToPostInCategory();
|
|
41
42
|
error CTPublisher_ZeroTotalSupply();
|
|
42
43
|
|
|
@@ -191,6 +192,9 @@ contract CTPublisher is JBPermissioned, ERC2771Context, ICTPublisher {
|
|
|
191
192
|
payable
|
|
192
193
|
override
|
|
193
194
|
{
|
|
195
|
+
// Reject empty posts to prevent fee-free metadata shadowing.
|
|
196
|
+
if (posts.length == 0) revert CTPublisher_NoPosts();
|
|
197
|
+
|
|
194
198
|
// Keep a reference to the amount being paid, which is msg.value minus the fee.
|
|
195
199
|
uint256 payValue = msg.value;
|
|
196
200
|
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
pragma solidity 0.8.28;
|
|
3
|
+
|
|
4
|
+
// forge-lint: disable-next-line(unaliased-plain-import)
|
|
5
|
+
import "forge-std/Test.sol";
|
|
6
|
+
|
|
7
|
+
import {IJBPermissions} from "@bananapus/core-v6/src/interfaces/IJBPermissions.sol";
|
|
8
|
+
import {IJBDirectory} from "@bananapus/core-v6/src/interfaces/IJBDirectory.sol";
|
|
9
|
+
import {IJB721TiersHook} from "@bananapus/721-hook-v6/src/interfaces/IJB721TiersHook.sol";
|
|
10
|
+
|
|
11
|
+
import {CTPublisher} from "../../src/CTPublisher.sol";
|
|
12
|
+
import {CTPost} from "../../src/structs/CTPost.sol";
|
|
13
|
+
|
|
14
|
+
/// @title M24_EmptyPostFeeBypass
|
|
15
|
+
/// @notice Verifies that calling mintFrom with an empty posts array reverts,
|
|
16
|
+
/// preventing fee-free metadata shadowing via additionalPayMetadata.
|
|
17
|
+
contract M24_EmptyPostFeeBypass is Test {
|
|
18
|
+
CTPublisher publisher;
|
|
19
|
+
|
|
20
|
+
IJBPermissions permissions = IJBPermissions(makeAddr("permissions"));
|
|
21
|
+
IJBDirectory directory = IJBDirectory(makeAddr("directory"));
|
|
22
|
+
address hookAddr = makeAddr("hook");
|
|
23
|
+
address poster = makeAddr("poster");
|
|
24
|
+
|
|
25
|
+
uint256 feeProjectId = 1;
|
|
26
|
+
|
|
27
|
+
function setUp() public {
|
|
28
|
+
publisher = new CTPublisher(directory, permissions, feeProjectId, address(0));
|
|
29
|
+
vm.deal(poster, 10 ether);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/// @notice mintFrom with empty posts should revert with CTPublisher_NoPosts.
|
|
33
|
+
function test_revert_emptyPostsArray() public {
|
|
34
|
+
CTPost[] memory emptyPosts = new CTPost[](0);
|
|
35
|
+
|
|
36
|
+
vm.prank(poster);
|
|
37
|
+
vm.expectRevert(CTPublisher.CTPublisher_NoPosts.selector);
|
|
38
|
+
publisher.mintFrom{value: 1 ether}(IJB721TiersHook(hookAddr), emptyPosts, poster, poster, "", "");
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/// @notice mintFrom with empty posts and crafted additionalPayMetadata should still revert.
|
|
42
|
+
function test_revert_emptyPostsWithMetadata() public {
|
|
43
|
+
CTPost[] memory emptyPosts = new CTPost[](0);
|
|
44
|
+
|
|
45
|
+
// Attacker preloads additionalPayMetadata with hook mint metadata.
|
|
46
|
+
bytes memory craftedMetadata =
|
|
47
|
+
abi.encodePacked(bytes32(uint256(1)), bytes4(0xdeadbeef), uint256(32), uint256(1));
|
|
48
|
+
|
|
49
|
+
vm.prank(poster);
|
|
50
|
+
vm.expectRevert(CTPublisher.CTPublisher_NoPosts.selector);
|
|
51
|
+
publisher.mintFrom{value: 1 ether}(IJB721TiersHook(hookAddr), emptyPosts, poster, poster, craftedMetadata, "");
|
|
52
|
+
}
|
|
53
|
+
}
|