@croptop/core-v6 0.0.38 → 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.
- package/README.md +2 -2
- package/foundry.toml +2 -1
- package/package.json +25 -13
- package/script/ConfigureFeeProject.s.sol +8 -5
- package/src/CTDeployer.sol +52 -51
- package/src/interfaces/ICTDeployer.sol +2 -2
- package/ADMINISTRATION.md +0 -94
- package/ARCHITECTURE.md +0 -96
- package/AUDIT_INSTRUCTIONS.md +0 -88
- package/RISKS.md +0 -78
- package/SKILLS.md +0 -46
- package/STYLE_GUIDE.md +0 -610
- package/USER_JOURNEYS.md +0 -134
- package/foundry.lock +0 -11
- package/slither-ci.config.json +0 -10
- package/sphinx.lock +0 -507
- package/test/CTDeployer.t.sol +0 -616
- package/test/CTProjectOwner.t.sol +0 -185
- package/test/CTPublisher.t.sol +0 -869
- package/test/ClaimCollectionOwnership.t.sol +0 -315
- package/test/CroptopAttacks.t.sol +0 -437
- package/test/Fork.t.sol +0 -227
- package/test/TestAuditGaps.sol +0 -696
- package/test/Test_MetadataGeneration.t.sol +0 -79
- package/test/audit/CodexNemesisCroptopPublisherBoundary.t.sol +0 -329
- package/test/audit/CodexNemesisCurrencyPoCs.t.sol +0 -371
- package/test/audit/CodexNemesisFreshRound.t.sol +0 -395
- package/test/audit/CodexNemesisMetadataShadow.t.sol +0 -196
- package/test/audit/CodexNemesisPoCs.t.sol +0 -263
- package/test/audit/CodexNemesisPolicyReuse.t.sol +0 -168
- package/test/audit/CodexNemesisUriDrift.t.sol +0 -252
- package/test/audit/DeployerPermissionBypass.t.sol +0 -213
- package/test/audit/EmptyPostFeeBypass.t.sol +0 -53
- package/test/audit/FeeBeneficiaryReentrancy.t.sol +0 -247
- package/test/audit/FeeFallbackBlackhole.t.sol +0 -263
- package/test/audit/Pass12Fixes.t.sol +0 -388
- package/test/fork/PublishFork.t.sol +0 -440
- package/test/regression/DuplicateUriFeeEvasion.t.sol +0 -312
- package/test/regression/FeeEvasion.t.sol +0 -286
- package/test/regression/StaleTierIdMapping.t.sol +0 -228
|
@@ -1,371 +0,0 @@
|
|
|
1
|
-
// SPDX-License-Identifier: MIT
|
|
2
|
-
pragma solidity ^0.8.17;
|
|
3
|
-
|
|
4
|
-
import "forge-std/Test.sol";
|
|
5
|
-
|
|
6
|
-
import {JBPermissions} from "@bananapus/core-v6/src/JBPermissions.sol";
|
|
7
|
-
import {JBProjects} from "@bananapus/core-v6/src/JBProjects.sol";
|
|
8
|
-
import {JBDirectory} from "@bananapus/core-v6/src/JBDirectory.sol";
|
|
9
|
-
import {JBRulesets} from "@bananapus/core-v6/src/JBRulesets.sol";
|
|
10
|
-
import {JBTokens} from "@bananapus/core-v6/src/JBTokens.sol";
|
|
11
|
-
import {JBERC20} from "@bananapus/core-v6/src/JBERC20.sol";
|
|
12
|
-
import {JBSplits} from "@bananapus/core-v6/src/JBSplits.sol";
|
|
13
|
-
import {JBPrices} from "@bananapus/core-v6/src/JBPrices.sol";
|
|
14
|
-
import {JBController} from "@bananapus/core-v6/src/JBController.sol";
|
|
15
|
-
import {JBFundAccessLimits} from "@bananapus/core-v6/src/JBFundAccessLimits.sol";
|
|
16
|
-
import {JBMultiTerminal} from "@bananapus/core-v6/src/JBMultiTerminal.sol";
|
|
17
|
-
import {JBTerminalStore} from "@bananapus/core-v6/src/JBTerminalStore.sol";
|
|
18
|
-
import {JBFeelessAddresses} from "@bananapus/core-v6/src/JBFeelessAddresses.sol";
|
|
19
|
-
import {IJBTerminal} from "@bananapus/core-v6/src/interfaces/IJBTerminal.sol";
|
|
20
|
-
import {JBConstants} from "@bananapus/core-v6/src/libraries/JBConstants.sol";
|
|
21
|
-
import {JBCurrencyIds} from "@bananapus/core-v6/src/libraries/JBCurrencyIds.sol";
|
|
22
|
-
import {JBPermissionIds} from "@bananapus/permission-ids-v6/src/JBPermissionIds.sol";
|
|
23
|
-
import {JBAccountingContext} from "@bananapus/core-v6/src/structs/JBAccountingContext.sol";
|
|
24
|
-
import {JBPermissionsData} from "@bananapus/core-v6/src/structs/JBPermissionsData.sol";
|
|
25
|
-
import {JBRulesetConfig} from "@bananapus/core-v6/src/structs/JBRulesetConfig.sol";
|
|
26
|
-
import {JBSplit} from "@bananapus/core-v6/src/structs/JBSplit.sol";
|
|
27
|
-
import {JBTerminalConfig} from "@bananapus/core-v6/src/structs/JBTerminalConfig.sol";
|
|
28
|
-
import {MockPriceFeed} from "@bananapus/core-v6/test/mock/MockPriceFeed.sol";
|
|
29
|
-
|
|
30
|
-
import {JB721TiersHookStore} from "@bananapus/721-hook-v6/src/JB721TiersHookStore.sol";
|
|
31
|
-
import {JB721TiersHook} from "@bananapus/721-hook-v6/src/JB721TiersHook.sol";
|
|
32
|
-
import {JB721TiersHookDeployer} from "@bananapus/721-hook-v6/src/JB721TiersHookDeployer.sol";
|
|
33
|
-
import {JB721CheckpointsDeployer} from "@bananapus/721-hook-v6/src/JB721CheckpointsDeployer.sol";
|
|
34
|
-
import {IJB721TiersHook} from "@bananapus/721-hook-v6/src/interfaces/IJB721TiersHook.sol";
|
|
35
|
-
import {IJB721TokenUriResolver} from "@bananapus/721-hook-v6/src/interfaces/IJB721TokenUriResolver.sol";
|
|
36
|
-
import {JB721InitTiersConfig} from "@bananapus/721-hook-v6/src/structs/JB721InitTiersConfig.sol";
|
|
37
|
-
import {JB721TierConfig} from "@bananapus/721-hook-v6/src/structs/JB721TierConfig.sol";
|
|
38
|
-
import {JB721TiersHookFlags} from "@bananapus/721-hook-v6/src/structs/JB721TiersHookFlags.sol";
|
|
39
|
-
import {JBDeploy721TiersHookConfig} from "@bananapus/721-hook-v6/src/structs/JBDeploy721TiersHookConfig.sol";
|
|
40
|
-
import {JBAddressRegistry} from "@bananapus/address-registry-v6/src/JBAddressRegistry.sol";
|
|
41
|
-
|
|
42
|
-
import {JBSuckerRegistry} from "@bananapus/suckers-v6/src/JBSuckerRegistry.sol";
|
|
43
|
-
import {IPermit2} from "@uniswap/permit2/src/interfaces/IPermit2.sol";
|
|
44
|
-
import {DeployPermit2} from "@uniswap/permit2/test/utils/DeployPermit2.sol";
|
|
45
|
-
|
|
46
|
-
import {CTDeployer} from "../../src/CTDeployer.sol";
|
|
47
|
-
import {CTPublisher} from "../../src/CTPublisher.sol";
|
|
48
|
-
import {CTAllowedPost} from "../../src/structs/CTAllowedPost.sol";
|
|
49
|
-
import {CTDeployerAllowedPost} from "../../src/structs/CTDeployerAllowedPost.sol";
|
|
50
|
-
import {CTPost} from "../../src/structs/CTPost.sol";
|
|
51
|
-
import {CTProjectConfig} from "../../src/structs/CTProjectConfig.sol";
|
|
52
|
-
import {CTSuckerDeploymentConfig} from "../../src/structs/CTSuckerDeploymentConfig.sol";
|
|
53
|
-
import {JBSuckerDeployerConfig} from "@bananapus/suckers-v6/src/structs/JBSuckerDeployerConfig.sol";
|
|
54
|
-
|
|
55
|
-
contract CodexNemesisCurrencyPoCs is Test, DeployPermit2 {
|
|
56
|
-
address internal constant MULTISIG = address(0xBEEF);
|
|
57
|
-
address internal constant PROJECT_OWNER = address(0xA11CE);
|
|
58
|
-
address internal constant POSTER = address(0xB0B);
|
|
59
|
-
address internal constant NFT_BENEFICIARY = address(0xCAFE);
|
|
60
|
-
address internal constant FEE_BENEFICIARY = address(0xFEE);
|
|
61
|
-
|
|
62
|
-
uint104 internal constant POST_PRICE = 0.1 ether;
|
|
63
|
-
uint32 internal constant POST_SUPPLY = 100;
|
|
64
|
-
uint24 internal constant POST_CATEGORY = 1;
|
|
65
|
-
bytes32 internal constant TEST_URI = bytes32("nemesis-uri");
|
|
66
|
-
|
|
67
|
-
JBPermissions internal jbPermissions;
|
|
68
|
-
JBProjects internal jbProjects;
|
|
69
|
-
JBDirectory internal jbDirectory;
|
|
70
|
-
JBRulesets internal jbRulesets;
|
|
71
|
-
JBTokens internal jbTokens;
|
|
72
|
-
JBSplits internal jbSplits;
|
|
73
|
-
JBPrices internal jbPrices;
|
|
74
|
-
JBFundAccessLimits internal jbFundAccessLimits;
|
|
75
|
-
JBController internal jbController;
|
|
76
|
-
JBFeelessAddresses internal jbFeelessAddresses;
|
|
77
|
-
JBTerminalStore internal jbTerminalStore;
|
|
78
|
-
JBMultiTerminal internal jbMultiTerminal;
|
|
79
|
-
JB721TiersHookDeployer internal hookDeployer;
|
|
80
|
-
JBSuckerRegistry internal suckerRegistry;
|
|
81
|
-
|
|
82
|
-
function test_deployerProjectsNeedAnUndeclaredIdentityPriceFeed() public {
|
|
83
|
-
_deployCore();
|
|
84
|
-
_deployTerminal();
|
|
85
|
-
_deployHookInfra();
|
|
86
|
-
suckerRegistry = new JBSuckerRegistry(jbDirectory, jbPermissions, MULTISIG, address(0));
|
|
87
|
-
|
|
88
|
-
uint256 feeProjectId = _launchProject({
|
|
89
|
-
owner: PROJECT_OWNER,
|
|
90
|
-
baseCurrency: uint32(uint160(JBConstants.NATIVE_TOKEN)),
|
|
91
|
-
dataHook: address(0),
|
|
92
|
-
useDataHookForPay: false,
|
|
93
|
-
useDataHookForCashOut: false
|
|
94
|
-
});
|
|
95
|
-
|
|
96
|
-
CTPublisher publisher = new CTPublisher(jbDirectory, jbPermissions, feeProjectId, address(0));
|
|
97
|
-
CTDeployer deployer =
|
|
98
|
-
new CTDeployer(jbPermissions, jbProjects, hookDeployer, publisher, suckerRegistry, address(0));
|
|
99
|
-
|
|
100
|
-
(uint256 projectId, IJB721TiersHook hook) = _launchViaCTDeployer(deployer, PROJECT_OWNER);
|
|
101
|
-
assertEq(projectId, 2, "expected the first Croptop project to be project 2");
|
|
102
|
-
|
|
103
|
-
vm.deal(POSTER, 1 ether);
|
|
104
|
-
|
|
105
|
-
vm.prank(POSTER);
|
|
106
|
-
vm.expectRevert();
|
|
107
|
-
publisher.mintFrom{value: _totalValue()}(hook, _singlePost(), NFT_BENEFICIARY, FEE_BENEFICIARY, "", "");
|
|
108
|
-
|
|
109
|
-
MockPriceFeed identityFeed = new MockPriceFeed(1e18, 18);
|
|
110
|
-
vm.prank(MULTISIG);
|
|
111
|
-
jbPrices.addPriceFeedFor({
|
|
112
|
-
projectId: 0,
|
|
113
|
-
pricingCurrency: uint32(uint160(JBConstants.NATIVE_TOKEN)),
|
|
114
|
-
unitCurrency: JBCurrencyIds.ETH,
|
|
115
|
-
feed: identityFeed
|
|
116
|
-
});
|
|
117
|
-
|
|
118
|
-
vm.prank(POSTER);
|
|
119
|
-
publisher.mintFrom{value: _totalValue()}(hook, _singlePost(), NFT_BENEFICIARY, FEE_BENEFICIARY, "", "");
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
function test_misconfiguredFeeProjectRefundsAllCroptopFees() public {
|
|
123
|
-
_deployCore();
|
|
124
|
-
_deployTerminal();
|
|
125
|
-
_deployHookInfra();
|
|
126
|
-
|
|
127
|
-
uint256 feeProjectId = _launchProject({
|
|
128
|
-
owner: PROJECT_OWNER,
|
|
129
|
-
baseCurrency: JBCurrencyIds.ETH,
|
|
130
|
-
dataHook: address(0),
|
|
131
|
-
useDataHookForPay: false,
|
|
132
|
-
useDataHookForCashOut: false
|
|
133
|
-
});
|
|
134
|
-
|
|
135
|
-
CTPublisher publisher = new CTPublisher(jbDirectory, jbPermissions, feeProjectId, address(0));
|
|
136
|
-
|
|
137
|
-
(uint256 projectId, IJB721TiersHook hook) = _launchDirectProjectWithHook({
|
|
138
|
-
publisher: publisher, owner: PROJECT_OWNER, baseCurrency: uint32(uint160(JBConstants.NATIVE_TOKEN))
|
|
139
|
-
});
|
|
140
|
-
assertEq(projectId, 2, "expected the publish target to be project 2");
|
|
141
|
-
|
|
142
|
-
vm.deal(POSTER, 1 ether);
|
|
143
|
-
uint256 posterBalanceBefore = POSTER.balance;
|
|
144
|
-
uint256 feeProjectBalanceBefore =
|
|
145
|
-
jbTerminalStore.balanceOf(address(jbMultiTerminal), feeProjectId, JBConstants.NATIVE_TOKEN);
|
|
146
|
-
uint256 targetBalanceBefore =
|
|
147
|
-
jbTerminalStore.balanceOf(address(jbMultiTerminal), projectId, JBConstants.NATIVE_TOKEN);
|
|
148
|
-
|
|
149
|
-
vm.prank(POSTER);
|
|
150
|
-
publisher.mintFrom{value: _totalValue()}(hook, _singlePost(), NFT_BENEFICIARY, FEE_BENEFICIARY, "", "");
|
|
151
|
-
|
|
152
|
-
uint256 feeProjectBalanceAfter =
|
|
153
|
-
jbTerminalStore.balanceOf(address(jbMultiTerminal), feeProjectId, JBConstants.NATIVE_TOKEN);
|
|
154
|
-
uint256 targetBalanceAfter =
|
|
155
|
-
jbTerminalStore.balanceOf(address(jbMultiTerminal), projectId, JBConstants.NATIVE_TOKEN);
|
|
156
|
-
|
|
157
|
-
assertEq(feeProjectBalanceAfter - feeProjectBalanceBefore, 0, "fee project should not receive the fee");
|
|
158
|
-
assertEq(targetBalanceAfter - targetBalanceBefore, POST_PRICE, "target project should still receive the post");
|
|
159
|
-
assertEq(
|
|
160
|
-
posterBalanceBefore - POSTER.balance,
|
|
161
|
-
POST_PRICE,
|
|
162
|
-
"the fee should be refunded back to the caller after the fee-project pay reverts"
|
|
163
|
-
);
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
function _deployCore() internal {
|
|
167
|
-
jbPermissions = new JBPermissions(address(0));
|
|
168
|
-
jbProjects = new JBProjects(MULTISIG, address(0), address(0));
|
|
169
|
-
jbDirectory = new JBDirectory(jbPermissions, jbProjects, MULTISIG);
|
|
170
|
-
JBERC20 jbErc20 = new JBERC20(jbPermissions, jbProjects);
|
|
171
|
-
jbTokens = new JBTokens(jbDirectory, jbErc20);
|
|
172
|
-
jbRulesets = new JBRulesets(jbDirectory);
|
|
173
|
-
jbPrices = new JBPrices(jbDirectory, jbPermissions, jbProjects, MULTISIG, address(0));
|
|
174
|
-
jbSplits = new JBSplits(jbDirectory);
|
|
175
|
-
jbFundAccessLimits = new JBFundAccessLimits(jbDirectory);
|
|
176
|
-
|
|
177
|
-
jbController = new JBController(
|
|
178
|
-
jbDirectory,
|
|
179
|
-
jbFundAccessLimits,
|
|
180
|
-
jbPermissions,
|
|
181
|
-
jbPrices,
|
|
182
|
-
jbProjects,
|
|
183
|
-
jbRulesets,
|
|
184
|
-
jbSplits,
|
|
185
|
-
jbTokens,
|
|
186
|
-
address(0),
|
|
187
|
-
address(0)
|
|
188
|
-
);
|
|
189
|
-
|
|
190
|
-
vm.prank(MULTISIG);
|
|
191
|
-
jbDirectory.setIsAllowedToSetFirstController(address(jbController), true);
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
function _deployTerminal() internal {
|
|
195
|
-
jbFeelessAddresses = new JBFeelessAddresses(MULTISIG);
|
|
196
|
-
jbTerminalStore = new JBTerminalStore(jbDirectory, jbPrices, jbRulesets);
|
|
197
|
-
|
|
198
|
-
address permit2 = deployPermit2();
|
|
199
|
-
|
|
200
|
-
jbMultiTerminal = new JBMultiTerminal(
|
|
201
|
-
jbFeelessAddresses,
|
|
202
|
-
jbPermissions,
|
|
203
|
-
jbProjects,
|
|
204
|
-
jbSplits,
|
|
205
|
-
jbTerminalStore,
|
|
206
|
-
jbTokens,
|
|
207
|
-
IPermit2(permit2),
|
|
208
|
-
address(0)
|
|
209
|
-
);
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
function _deployHookInfra() internal {
|
|
213
|
-
JB721TiersHookStore store = new JB721TiersHookStore();
|
|
214
|
-
JBAddressRegistry addressRegistry = new JBAddressRegistry();
|
|
215
|
-
JB721CheckpointsDeployer checkpointsDeployer = new JB721CheckpointsDeployer();
|
|
216
|
-
|
|
217
|
-
JB721TiersHook hookImpl = new JB721TiersHook(
|
|
218
|
-
jbDirectory, jbPermissions, jbPrices, jbRulesets, store, jbSplits, checkpointsDeployer, address(0)
|
|
219
|
-
);
|
|
220
|
-
|
|
221
|
-
hookDeployer = new JB721TiersHookDeployer(hookImpl, store, addressRegistry, address(0));
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
function _launchProject(
|
|
225
|
-
address owner,
|
|
226
|
-
uint32 baseCurrency,
|
|
227
|
-
address dataHook,
|
|
228
|
-
bool useDataHookForPay,
|
|
229
|
-
bool useDataHookForCashOut
|
|
230
|
-
)
|
|
231
|
-
internal
|
|
232
|
-
returns (uint256 projectId)
|
|
233
|
-
{
|
|
234
|
-
JBRulesetConfig[] memory rulesetConfigs = new JBRulesetConfig[](1);
|
|
235
|
-
rulesetConfigs[0].weight = 1_000_000 * (10 ** 18);
|
|
236
|
-
rulesetConfigs[0].metadata.baseCurrency = baseCurrency;
|
|
237
|
-
rulesetConfigs[0].metadata.dataHook = dataHook;
|
|
238
|
-
rulesetConfigs[0].metadata.useDataHookForPay = useDataHookForPay;
|
|
239
|
-
rulesetConfigs[0].metadata.useDataHookForCashOut = useDataHookForCashOut;
|
|
240
|
-
|
|
241
|
-
projectId = jbController.launchProjectFor({
|
|
242
|
-
owner: owner,
|
|
243
|
-
projectUri: "ipfs://project",
|
|
244
|
-
rulesetConfigurations: rulesetConfigs,
|
|
245
|
-
terminalConfigurations: _ethTerminalConfig(),
|
|
246
|
-
memo: "nemesis launch"
|
|
247
|
-
});
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
function _launchViaCTDeployer(
|
|
251
|
-
CTDeployer deployer,
|
|
252
|
-
address owner
|
|
253
|
-
)
|
|
254
|
-
internal
|
|
255
|
-
returns (uint256 projectId, IJB721TiersHook hook)
|
|
256
|
-
{
|
|
257
|
-
CTDeployerAllowedPost[] memory allowedPosts = new CTDeployerAllowedPost[](1);
|
|
258
|
-
allowedPosts[0] = CTDeployerAllowedPost({
|
|
259
|
-
category: POST_CATEGORY,
|
|
260
|
-
minimumPrice: 0,
|
|
261
|
-
minimumTotalSupply: 1,
|
|
262
|
-
maximumTotalSupply: 10_000,
|
|
263
|
-
maximumSplitPercent: 0,
|
|
264
|
-
allowedAddresses: new address[](0)
|
|
265
|
-
});
|
|
266
|
-
|
|
267
|
-
CTProjectConfig memory config = CTProjectConfig({
|
|
268
|
-
terminalConfigurations: _ethTerminalConfig(),
|
|
269
|
-
projectUri: "ipfs://croptop",
|
|
270
|
-
allowedPosts: allowedPosts,
|
|
271
|
-
contractUri: "ipfs://contract",
|
|
272
|
-
name: "Croptop",
|
|
273
|
-
symbol: "CROP",
|
|
274
|
-
salt: bytes32(uint256(1))
|
|
275
|
-
});
|
|
276
|
-
|
|
277
|
-
CTSuckerDeploymentConfig memory suckerConfig =
|
|
278
|
-
CTSuckerDeploymentConfig({deployerConfigurations: new JBSuckerDeployerConfig[](0), salt: bytes32(0)});
|
|
279
|
-
|
|
280
|
-
(projectId, hook) = deployer.deployProjectFor(owner, config, suckerConfig, jbController);
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
function _launchDirectProjectWithHook(
|
|
284
|
-
CTPublisher publisher,
|
|
285
|
-
address owner,
|
|
286
|
-
uint32 baseCurrency
|
|
287
|
-
)
|
|
288
|
-
internal
|
|
289
|
-
returns (uint256 projectId, IJB721TiersHook hook)
|
|
290
|
-
{
|
|
291
|
-
projectId = jbProjects.count() + 1;
|
|
292
|
-
hook = hookDeployer.deployHookFor({
|
|
293
|
-
projectId: projectId,
|
|
294
|
-
deployTiersHookConfig: JBDeploy721TiersHookConfig({
|
|
295
|
-
name: "DirectCrop",
|
|
296
|
-
symbol: "DIR",
|
|
297
|
-
baseUri: "ipfs://",
|
|
298
|
-
tokenUriResolver: IJB721TokenUriResolver(address(0)),
|
|
299
|
-
contractUri: "ipfs://contract",
|
|
300
|
-
tiersConfig: JB721InitTiersConfig({
|
|
301
|
-
tiers: new JB721TierConfig[](0), currency: uint32(uint160(JBConstants.NATIVE_TOKEN)), decimals: 18
|
|
302
|
-
}),
|
|
303
|
-
flags: JB721TiersHookFlags({
|
|
304
|
-
noNewTiersWithReserves: false,
|
|
305
|
-
noNewTiersWithVotes: false,
|
|
306
|
-
noNewTiersWithOwnerMinting: false,
|
|
307
|
-
preventOverspending: false,
|
|
308
|
-
issueTokensForSplits: false
|
|
309
|
-
})
|
|
310
|
-
}),
|
|
311
|
-
salt: bytes32(uint256(2))
|
|
312
|
-
});
|
|
313
|
-
|
|
314
|
-
uint256 launchedProjectId = _launchProject({
|
|
315
|
-
owner: owner,
|
|
316
|
-
baseCurrency: baseCurrency,
|
|
317
|
-
dataHook: address(hook),
|
|
318
|
-
useDataHookForPay: true,
|
|
319
|
-
useDataHookForCashOut: true
|
|
320
|
-
});
|
|
321
|
-
assertEq(launchedProjectId, projectId, "hook/project ids should stay aligned");
|
|
322
|
-
|
|
323
|
-
uint8[] memory permissionIds = new uint8[](1);
|
|
324
|
-
permissionIds[0] = JBPermissionIds.ADJUST_721_TIERS;
|
|
325
|
-
jbPermissions.setPermissionsFor({
|
|
326
|
-
account: address(this),
|
|
327
|
-
permissionsData: JBPermissionsData({
|
|
328
|
-
operator: address(publisher), projectId: uint64(projectId), permissionIds: permissionIds
|
|
329
|
-
})
|
|
330
|
-
});
|
|
331
|
-
|
|
332
|
-
CTAllowedPost[] memory allowedPosts = new CTAllowedPost[](1);
|
|
333
|
-
allowedPosts[0] = CTAllowedPost({
|
|
334
|
-
hook: address(hook),
|
|
335
|
-
category: POST_CATEGORY,
|
|
336
|
-
minimumPrice: 0,
|
|
337
|
-
minimumTotalSupply: 1,
|
|
338
|
-
maximumTotalSupply: 10_000,
|
|
339
|
-
maximumSplitPercent: 0,
|
|
340
|
-
allowedAddresses: new address[](0)
|
|
341
|
-
});
|
|
342
|
-
publisher.configurePostingCriteriaFor(allowedPosts);
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
function _ethTerminalConfig() internal view returns (JBTerminalConfig[] memory configs) {
|
|
346
|
-
JBAccountingContext[] memory contexts = new JBAccountingContext[](1);
|
|
347
|
-
contexts[0] = JBAccountingContext({
|
|
348
|
-
token: JBConstants.NATIVE_TOKEN, decimals: 18, currency: uint32(uint160(JBConstants.NATIVE_TOKEN))
|
|
349
|
-
});
|
|
350
|
-
|
|
351
|
-
configs = new JBTerminalConfig[](1);
|
|
352
|
-
configs[0] =
|
|
353
|
-
JBTerminalConfig({terminal: IJBTerminal(address(jbMultiTerminal)), accountingContextsToAccept: contexts});
|
|
354
|
-
}
|
|
355
|
-
|
|
356
|
-
function _singlePost() internal pure returns (CTPost[] memory posts) {
|
|
357
|
-
posts = new CTPost[](1);
|
|
358
|
-
posts[0] = CTPost({
|
|
359
|
-
encodedIPFSUri: TEST_URI,
|
|
360
|
-
price: POST_PRICE,
|
|
361
|
-
totalSupply: POST_SUPPLY,
|
|
362
|
-
category: POST_CATEGORY,
|
|
363
|
-
splitPercent: 0,
|
|
364
|
-
splits: new JBSplit[](0)
|
|
365
|
-
});
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
function _totalValue() internal pure returns (uint256) {
|
|
369
|
-
return POST_PRICE + (POST_PRICE / 20);
|
|
370
|
-
}
|
|
371
|
-
}
|