@croptop/core-v6 0.0.37 → 0.0.39

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.
Files changed (40) hide show
  1. package/README.md +2 -2
  2. package/foundry.toml +2 -1
  3. package/package.json +25 -13
  4. package/script/ConfigureFeeProject.s.sol +8 -5
  5. package/src/CTDeployer.sol +52 -51
  6. package/src/CTPublisher.sol +20 -5
  7. package/src/interfaces/ICTDeployer.sol +2 -2
  8. package/ADMINISTRATION.md +0 -94
  9. package/ARCHITECTURE.md +0 -96
  10. package/AUDIT_INSTRUCTIONS.md +0 -88
  11. package/RISKS.md +0 -78
  12. package/SKILLS.md +0 -46
  13. package/STYLE_GUIDE.md +0 -610
  14. package/USER_JOURNEYS.md +0 -134
  15. package/foundry.lock +0 -11
  16. package/slither-ci.config.json +0 -10
  17. package/sphinx.lock +0 -507
  18. package/test/CTDeployer.t.sol +0 -616
  19. package/test/CTProjectOwner.t.sol +0 -185
  20. package/test/CTPublisher.t.sol +0 -869
  21. package/test/ClaimCollectionOwnership.t.sol +0 -315
  22. package/test/CroptopAttacks.t.sol +0 -437
  23. package/test/Fork.t.sol +0 -227
  24. package/test/TestAuditGaps.sol +0 -696
  25. package/test/Test_MetadataGeneration.t.sol +0 -79
  26. package/test/audit/CodexNemesisCroptopPublisherBoundary.t.sol +0 -329
  27. package/test/audit/CodexNemesisCurrencyPoCs.t.sol +0 -371
  28. package/test/audit/CodexNemesisFreshRound.t.sol +0 -395
  29. package/test/audit/CodexNemesisMetadataShadow.t.sol +0 -203
  30. package/test/audit/CodexNemesisPoCs.t.sol +0 -263
  31. package/test/audit/CodexNemesisPolicyReuse.t.sol +0 -168
  32. package/test/audit/CodexNemesisUriDrift.t.sol +0 -252
  33. package/test/audit/DeployerPermissionBypass.t.sol +0 -213
  34. package/test/audit/EmptyPostFeeBypass.t.sol +0 -53
  35. package/test/audit/FeeBeneficiaryReentrancy.t.sol +0 -247
  36. package/test/audit/FeeFallbackBlackhole.t.sol +0 -263
  37. package/test/fork/PublishFork.t.sol +0 -440
  38. package/test/regression/DuplicateUriFeeEvasion.t.sol +0 -312
  39. package/test/regression/FeeEvasion.t.sol +0 -286
  40. package/test/regression/StaleTierIdMapping.t.sol +0 -218
@@ -1,263 +0,0 @@
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 {IJB721TiersHook} from "@bananapus/721-hook-v6/src/interfaces/IJB721TiersHook.sol";
8
- import {IJB721TiersHookStore} from "@bananapus/721-hook-v6/src/interfaces/IJB721TiersHookStore.sol";
9
- import {JB721Tier} from "@bananapus/721-hook-v6/src/structs/JB721Tier.sol";
10
- import {JB721TierConfig} from "@bananapus/721-hook-v6/src/structs/JB721TierConfig.sol";
11
- import {IJBDirectory} from "@bananapus/core-v6/src/interfaces/IJBDirectory.sol";
12
- import {IJBPermissions} from "@bananapus/core-v6/src/interfaces/IJBPermissions.sol";
13
- import {IJBTerminal} from "@bananapus/core-v6/src/interfaces/IJBTerminal.sol";
14
- import {JBPermissionsData} from "@bananapus/core-v6/src/structs/JBPermissionsData.sol";
15
- import {JBSplit} from "@bananapus/core-v6/src/structs/JBSplit.sol";
16
-
17
- import {CTPublisher} from "../../src/CTPublisher.sol";
18
- import {CTAllowedPost} from "../../src/structs/CTAllowedPost.sol";
19
- import {CTPost} from "../../src/structs/CTPost.sol";
20
-
21
- contract BlackholeMockPermissions is IJBPermissions {
22
- // forge-lint: disable-next-line(mixed-case-function)
23
- function WILDCARD_PROJECT_ID() external pure returns (uint256) {
24
- return 0;
25
- }
26
-
27
- function permissionsOf(address, address, uint256) external pure returns (uint256) {
28
- return 0;
29
- }
30
-
31
- function hasPermission(address, address, uint256, uint256, bool, bool) external pure returns (bool) {
32
- return true;
33
- }
34
-
35
- function hasPermissions(address, address, uint256, uint256[] calldata, bool, bool) external pure returns (bool) {
36
- return true;
37
- }
38
-
39
- function setPermissionsFor(address, JBPermissionsData calldata) external {}
40
- }
41
-
42
- contract BlackholeMockStore {
43
- function maxTierIdOf(address) external pure returns (uint256) {
44
- return 0;
45
- }
46
-
47
- function isTierRemoved(address, uint256) external pure returns (bool) {
48
- return false;
49
- }
50
-
51
- function tierOf(address, uint256, bool) external pure returns (JB721Tier memory tier) {
52
- return tier;
53
- }
54
- }
55
-
56
- contract BlackholeMockHook {
57
- uint256 public immutable PROJECT_ID;
58
- IJB721TiersHookStore public immutable STORE;
59
- address public immutable OWNER;
60
-
61
- constructor(uint256 projectId, IJB721TiersHookStore store_, address owner_) {
62
- PROJECT_ID = projectId;
63
- STORE = store_;
64
- OWNER = owner_;
65
- }
66
-
67
- function adjustTiers(JB721TierConfig[] calldata, uint256[] calldata) external {}
68
-
69
- function METADATA_ID_TARGET() external view returns (address) {
70
- return address(this);
71
- }
72
-
73
- function owner() external view returns (address) {
74
- return OWNER;
75
- }
76
- }
77
-
78
- contract AcceptingProjectTerminal {
79
- uint256 public totalReceived;
80
-
81
- function pay(
82
- uint256,
83
- address,
84
- uint256,
85
- address,
86
- uint256,
87
- string calldata,
88
- bytes calldata
89
- )
90
- external
91
- payable
92
- returns (uint256)
93
- {
94
- totalReceived += msg.value;
95
- return 0;
96
- }
97
- }
98
-
99
- contract RevertingFeeTerminal {
100
- error FeeTerminalDown();
101
-
102
- function pay(
103
- uint256,
104
- address,
105
- uint256,
106
- address,
107
- uint256,
108
- string calldata,
109
- bytes calldata
110
- )
111
- external
112
- payable
113
- returns (uint256)
114
- {
115
- revert FeeTerminalDown();
116
- }
117
- }
118
-
119
- contract BlackholeDirectory {
120
- address public projectTerminal;
121
- address public feeTerminal;
122
-
123
- function setTerminals(address projectTerminal_, address feeTerminal_) external {
124
- projectTerminal = projectTerminal_;
125
- feeTerminal = feeTerminal_;
126
- }
127
-
128
- function primaryTerminalOf(uint256 projectId, address) external view returns (IJBTerminal) {
129
- return IJBTerminal(projectId == 1 ? feeTerminal : projectTerminal);
130
- }
131
- }
132
-
133
- contract RejectingFeeBeneficiary {
134
- receive() external payable {
135
- revert("no fee");
136
- }
137
- }
138
-
139
- contract RejectingMintCaller {
140
- function execute(
141
- CTPublisher publisher,
142
- IJB721TiersHook hook,
143
- CTPost[] memory posts,
144
- address nftBeneficiary,
145
- address feeBeneficiary
146
- )
147
- external
148
- payable
149
- {
150
- publisher.mintFrom{value: msg.value}(hook, posts, nftBeneficiary, feeBeneficiary, bytes(""), bytes(""));
151
- }
152
-
153
- receive() external payable {
154
- revert("no refund");
155
- }
156
- }
157
-
158
- contract AcceptingMintCaller {
159
- function execute(
160
- CTPublisher publisher,
161
- IJB721TiersHook hook,
162
- CTPost[] memory posts,
163
- address nftBeneficiary,
164
- address feeBeneficiary
165
- )
166
- external
167
- payable
168
- {
169
- publisher.mintFrom{value: msg.value}(hook, posts, nftBeneficiary, feeBeneficiary, bytes(""), bytes(""));
170
- }
171
-
172
- receive() external payable {}
173
- }
174
-
175
- contract FeeFallbackBlackholeTest is Test {
176
- BlackholeMockPermissions permissions;
177
- BlackholeDirectory directory;
178
- BlackholeMockStore store;
179
- BlackholeMockHook hook;
180
- AcceptingProjectTerminal projectTerminal;
181
- RevertingFeeTerminal feeTerminal;
182
- RejectingFeeBeneficiary feeBeneficiary;
183
- RejectingMintCaller caller;
184
- AcceptingMintCaller acceptingCaller;
185
- CTPublisher publisher;
186
-
187
- function setUp() public {
188
- permissions = new BlackholeMockPermissions();
189
- directory = new BlackholeDirectory();
190
- store = new BlackholeMockStore();
191
- hook = new BlackholeMockHook(2, IJB721TiersHookStore(address(store)), address(this));
192
- projectTerminal = new AcceptingProjectTerminal();
193
- feeTerminal = new RevertingFeeTerminal();
194
- feeBeneficiary = new RejectingFeeBeneficiary();
195
- caller = new RejectingMintCaller();
196
- acceptingCaller = new AcceptingMintCaller();
197
- publisher = new CTPublisher(IJBDirectory(address(directory)), permissions, 1, address(0));
198
-
199
- directory.setTerminals(address(projectTerminal), address(feeTerminal));
200
-
201
- CTAllowedPost[] memory allowedPosts = new CTAllowedPost[](1);
202
- allowedPosts[0] = CTAllowedPost({
203
- hook: address(hook),
204
- category: 1,
205
- minimumPrice: 1,
206
- minimumTotalSupply: 1,
207
- maximumTotalSupply: type(uint32).max,
208
- maximumSplitPercent: 0,
209
- allowedAddresses: new address[](0)
210
- });
211
- publisher.configurePostingCriteriaFor(allowedPosts);
212
-
213
- vm.deal(address(caller), 105);
214
- vm.deal(address(acceptingCaller), 105);
215
- }
216
-
217
- function test_feePaymentFailure_refundsMsgSenderAndPreservesMint() public {
218
- CTPost[] memory posts = new CTPost[](1);
219
- posts[0] = CTPost({
220
- encodedIPFSUri: keccak256("post"),
221
- totalSupply: 1,
222
- price: 100,
223
- category: 1,
224
- splitPercent: 0,
225
- splits: new JBSplit[](0)
226
- });
227
-
228
- vm.prank(address(acceptingCaller));
229
- acceptingCaller.execute{value: 105}(
230
- publisher, IJB721TiersHook(address(hook)), posts, address(this), address(feeBeneficiary)
231
- );
232
-
233
- assertEq(projectTerminal.totalReceived(), 100, "main project payment should still succeed");
234
- assertEq(address(feeTerminal).balance, 0, "fee terminal should receive nothing after reverting");
235
- assertEq(address(feeBeneficiary).balance, 0, "fee beneficiary should receive nothing");
236
- assertEq(address(acceptingCaller).balance, 5, "caller should receive the refunded fee");
237
- assertEq(address(publisher).balance, 0, "publisher should not retain trapped fees");
238
- }
239
-
240
- function test_feePaymentFailure_revertsIfMsgSenderRejectsRefund() public {
241
- CTPost[] memory posts = new CTPost[](1);
242
- posts[0] = CTPost({
243
- encodedIPFSUri: keccak256("post"),
244
- totalSupply: 1,
245
- price: 100,
246
- category: 1,
247
- splitPercent: 0,
248
- splits: new JBSplit[](0)
249
- });
250
-
251
- vm.prank(address(caller));
252
- vm.expectRevert(abi.encodeWithSelector(CTPublisher.CTPublisher_FeePaymentFailed.selector, 5));
253
- caller.execute{value: 105}(
254
- publisher, IJB721TiersHook(address(hook)), posts, address(this), address(feeBeneficiary)
255
- );
256
-
257
- assertEq(projectTerminal.totalReceived(), 0, "main project payment should roll back with the fee failure");
258
- assertEq(address(feeTerminal).balance, 0, "fee terminal should receive nothing after reverting");
259
- assertEq(address(feeBeneficiary).balance, 0, "fee beneficiary should receive nothing");
260
- assertEq(address(caller).balance, 105, "caller should retain funds when the mint reverts");
261
- assertEq(address(publisher).balance, 0, "publisher should not retain trapped fees");
262
- }
263
- }