@bananapus/721-hook-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.
Files changed (78) hide show
  1. package/foundry.lock +1 -7
  2. package/foundry.toml +1 -1
  3. package/package.json +20 -9
  4. package/script/Deploy.s.sol +2 -2
  5. package/src/JB721Checkpoints.sol +60 -18
  6. package/src/JB721CheckpointsDeployer.sol +10 -5
  7. package/src/JB721TiersHook.sol +4 -1
  8. package/src/JB721TiersHookProjectDeployer.sol +68 -30
  9. package/src/interfaces/IJB721Checkpoints.sol +21 -14
  10. package/src/interfaces/IJB721CheckpointsDeployer.sol +6 -2
  11. package/src/interfaces/IJB721TiersHookProjectDeployer.sol +2 -0
  12. package/test/utils/AccessJBLib.sol +49 -0
  13. package/test/utils/ForTest_JB721TiersHook.sol +246 -0
  14. package/test/utils/TestBaseWorkflow.sol +213 -0
  15. package/test/utils/UnitTestSetup.sol +805 -0
  16. package/.gas-snapshot +0 -152
  17. package/ADMINISTRATION.md +0 -87
  18. package/ARCHITECTURE.md +0 -98
  19. package/AUDIT_INSTRUCTIONS.md +0 -77
  20. package/RISKS.md +0 -118
  21. package/SKILLS.md +0 -43
  22. package/STYLE_GUIDE.md +0 -610
  23. package/USER_JOURNEYS.md +0 -121
  24. package/assets/findings/nana-721-hook-v6-pashov-ai-audit-report-20260330-091257.md +0 -83
  25. package/slither-ci.config.json +0 -10
  26. package/test/721HookAttacks.t.sol +0 -408
  27. package/test/E2E/Pay_Mint_Redeem_E2E.t.sol +0 -985
  28. package/test/Fork.t.sol +0 -2346
  29. package/test/TestAuditGaps.sol +0 -1075
  30. package/test/TestCheckpoints.t.sol +0 -341
  31. package/test/TestSafeTransferReentrancy.t.sol +0 -305
  32. package/test/TestVotingUnitsLifecycle.t.sol +0 -313
  33. package/test/audit/AuditRegressions.t.sol +0 -83
  34. package/test/audit/CodexNemesisReserveSellout.t.sol +0 -66
  35. package/test/audit/CrossCurrencySplitNoPrices.t.sol +0 -123
  36. package/test/audit/FreshAudit.t.sol +0 -197
  37. package/test/audit/FutureTierPoC.t.sol +0 -39
  38. package/test/audit/FutureTierRemoval.t.sol +0 -47
  39. package/test/audit/Pass12L18.t.sol +0 -80
  40. package/test/audit/PayCreditsBypassTierSplits.t.sol +0 -200
  41. package/test/audit/ProjectDeployerAuth.t.sol +0 -266
  42. package/test/audit/RepoFindings.t.sol +0 -195
  43. package/test/audit/ReserveActivation.t.sol +0 -87
  44. package/test/audit/ReserveSlotProtection.t.sol +0 -273
  45. package/test/audit/RetroactiveReserveBeneficiaryDilution.t.sol +0 -149
  46. package/test/audit/SameCurrencyDecimalMismatch.t.sol +0 -249
  47. package/test/audit/SplitCreditsMismatch.t.sol +0 -219
  48. package/test/audit/SplitFailureRedistribution.t.sol +0 -143
  49. package/test/audit/USDTVoidReturnCompat.t.sol +0 -301
  50. package/test/fork/ERC20CashOutFork.t.sol +0 -633
  51. package/test/fork/ERC20TierSplitFork.t.sol +0 -596
  52. package/test/fork/IssueTokensForSplitsFork.t.sol +0 -516
  53. package/test/invariants/TierLifecycleInvariant.t.sol +0 -188
  54. package/test/invariants/TieredHookStoreInvariant.t.sol +0 -86
  55. package/test/invariants/handlers/TierLifecycleHandler.sol +0 -300
  56. package/test/invariants/handlers/TierStoreHandler.sol +0 -165
  57. package/test/regression/BrokenTerminalDoesNotDos.t.sol +0 -277
  58. package/test/regression/CacheTierLookup.t.sol +0 -190
  59. package/test/regression/ProjectDeployerRulesets.t.sol +0 -358
  60. package/test/regression/ReserveBeneficiaryOverwrite.t.sol +0 -155
  61. package/test/regression/SplitDistributionBugs.t.sol +0 -751
  62. package/test/regression/SplitNoBeneficiary.t.sol +0 -140
  63. package/test/unit/AuditFixes_Unit.t.sol +0 -624
  64. package/test/unit/JB721CheckpointsDeployer_AccessControl.t.sol +0 -116
  65. package/test/unit/JB721TiersRulesetMetadataResolver.t.sol +0 -144
  66. package/test/unit/JBBitmap.t.sol +0 -170
  67. package/test/unit/JBIpfsDecoder.t.sol +0 -136
  68. package/test/unit/TierSupplyReserveCheck.t.sol +0 -221
  69. package/test/unit/adjustTier_Unit.t.sol +0 -1942
  70. package/test/unit/deployer_Unit.t.sol +0 -114
  71. package/test/unit/getters_constructor_Unit.t.sol +0 -593
  72. package/test/unit/mintFor_mintReservesFor_Unit.t.sol +0 -452
  73. package/test/unit/pay_CrossCurrency_Unit.t.sol +0 -530
  74. package/test/unit/pay_Unit.t.sol +0 -1661
  75. package/test/unit/redeem_Unit.t.sol +0 -473
  76. package/test/unit/relayBeneficiary_Unit.t.sol +0 -182
  77. package/test/unit/splitHookDistribution_Unit.t.sol +0 -604
  78. package/test/unit/tierSplitRouting_Unit.t.sol +0 -757
@@ -0,0 +1,246 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity 0.8.28;
3
+
4
+ // forge-lint: disable-next-line(unaliased-plain-import)
5
+ import "../../src/interfaces/IJB721TiersHook.sol";
6
+ import {JB721TierFlags} from "../../src/structs/JB721TierFlags.sol";
7
+
8
+ // forge-lint: disable-next-line(unaliased-plain-import)
9
+ import "../../src/JB721TiersHook.sol";
10
+ // forge-lint: disable-next-line(unaliased-plain-import)
11
+ import "../../src/JB721TiersHookStore.sol";
12
+
13
+ import {JB721CheckpointsDeployer} from "../../src/JB721CheckpointsDeployer.sol";
14
+ import {IJB721CheckpointsDeployer} from "../../src/interfaces/IJB721CheckpointsDeployer.sol";
15
+
16
+ // forge-lint: disable-next-line(unaliased-plain-import)
17
+ import "../../src/structs/JBBitmapWord.sol";
18
+
19
+ // forge-lint: disable-next-line(unaliased-plain-import)
20
+ import "@bananapus/core-v6/src/structs/JBRulesetMetadata.sol";
21
+ // forge-lint: disable-next-line(unaliased-plain-import)
22
+ import "@bananapus/core-v6/src/interfaces/IJBPermissioned.sol";
23
+ import {MetadataResolverHelper} from "@bananapus/core-v6/test/helpers/MetadataResolverHelper.sol";
24
+
25
+ // forge-lint: disable-next-line(unaliased-plain-import)
26
+ import "@bananapus/core-v6/src/libraries/JBConstants.sol";
27
+
28
+ // forge-lint: disable-next-line(unaliased-plain-import)
29
+ import "./UnitTestSetup.sol"; // Only used to get the `PAY_HOOK_ID` and `CASH_OUT_HOOK_ID` constants.
30
+
31
+ interface IJB721TiersHookStore_ForTest is IJB721TiersHookStore {
32
+ // forge-lint: disable-next-line(mixed-case-function)
33
+ function ForTest_dumpTiersList(address nft) external view returns (JB721Tier[] memory tiers);
34
+ // forge-lint: disable-next-line(mixed-case-function)
35
+ function ForTest_setTier(address hook, uint256 index, JBStored721Tier calldata newTier) external;
36
+ // forge-lint: disable-next-line(mixed-case-function)
37
+ function ForTest_setTierVotingUnits(address hook, uint256 tierId, uint32 votingUnits) external;
38
+ // forge-lint: disable-next-line(mixed-case-function)
39
+ function ForTest_setBalanceOf(address hook, address holder, uint256 tier, uint256 balance) external;
40
+ // forge-lint: disable-next-line(mixed-case-function)
41
+ function ForTest_setReservesMintedFor(address hook, uint256 tier, uint256 amount) external;
42
+ // forge-lint: disable-next-line(mixed-case-function)
43
+ function ForTest_setIsTierRemoved(address hook, uint256 tokenId) external;
44
+ // forge-lint: disable-next-line(mixed-case-function)
45
+ function ForTest_packBools(
46
+ bool allowOwnerMint,
47
+ bool transfersPausable,
48
+ bool useVotingUnits,
49
+ bool cantBeRemoved,
50
+ bool cantIncreaseDiscountPercent,
51
+ bool cantBuyWithCredits
52
+ )
53
+ external
54
+ returns (uint8);
55
+ }
56
+
57
+ // A customized 721 tiers hook for testing purposes.
58
+ contract ForTest_JB721TiersHook is JB721TiersHook {
59
+ // forge-lint: disable-next-line(mixed-case-variable)
60
+ IJB721TiersHookStore_ForTest public test_store;
61
+ MetadataResolverHelper metadataHelper;
62
+
63
+ uint256 constant SURPLUS = 10e18;
64
+ uint256 constant CASH_OUT_TAX_RATE = JBConstants.MAX_CASH_OUT_TAX_RATE; // 40%
65
+ address _trustedForwarder = address(123_456);
66
+
67
+ /// @dev Bundles ForTest_JB721TiersHook constructor args to avoid stack-too-deep.
68
+ struct ForTestInitConfig {
69
+ uint256 projectId;
70
+ string name;
71
+ string symbol;
72
+ string baseUri;
73
+ IJB721TokenUriResolver tokenUriResolver;
74
+ string contractUri;
75
+ JB721TierConfig[] tiers;
76
+ JB721TiersHookFlags flags;
77
+ }
78
+
79
+ constructor(
80
+ ForTestInitConfig memory config,
81
+ IJBDirectory directory,
82
+ IJBPrices prices,
83
+ IJBRulesets rulesets,
84
+ IJB721TiersHookStore store,
85
+ IJBSplits splits
86
+ )
87
+ // The directory is also `IJBPermissioned`.
88
+ JB721TiersHook(
89
+ directory,
90
+ IJBPermissioned(address(directory)).PERMISSIONS(),
91
+ prices,
92
+ rulesets,
93
+ store,
94
+ splits,
95
+ IJB721CheckpointsDeployer(address(new JB721CheckpointsDeployer(store))),
96
+ _trustedForwarder
97
+ )
98
+ {
99
+ // Reset the _initialized flag set by the parent constructor so this test contract can initialize itself.
100
+ _initialized = false;
101
+ JB721TiersHook.initialize(
102
+ config.projectId,
103
+ config.name,
104
+ config.symbol,
105
+ config.baseUri,
106
+ config.tokenUriResolver,
107
+ config.contractUri,
108
+ JB721InitTiersConfig({
109
+ tiers: config.tiers, currency: uint32(uint160(JBConstants.NATIVE_TOKEN)), decimals: 18
110
+ }),
111
+ config.flags
112
+ );
113
+ test_store = IJB721TiersHookStore_ForTest(address(store));
114
+
115
+ metadataHelper = new MetadataResolverHelper();
116
+ }
117
+
118
+ // forge-lint: disable-next-line(mixed-case-function)
119
+ function ForTest_setOwnerOf(uint256 tokenId, address owner) public {
120
+ _owners[tokenId] = owner;
121
+ }
122
+
123
+ function burn(uint256[] memory tokenIds) public {
124
+ for (uint256 i; i < tokenIds.length; i++) {
125
+ _burn(tokenIds[i]);
126
+ }
127
+ STORE.recordBurn(tokenIds);
128
+ }
129
+ }
130
+
131
+ // A customized 721 tiers hook store for testing purposes.
132
+ contract ForTest_JB721TiersHookStore is JB721TiersHookStore, IJB721TiersHookStore_ForTest {
133
+ using JBBitmap for mapping(uint256 => uint256);
134
+ using JBBitmap for JBBitmapWord;
135
+
136
+ // forge-lint: disable-next-line(mixed-case-function)
137
+ function ForTest_dumpTiersList(address nft) public view override returns (JB721Tier[] memory tiers) {
138
+ // Keep a reference to the max tier ID.
139
+ uint256 maxTierId = maxTierIdOf[nft];
140
+ // Initialize an array with the appropriate length.
141
+ tiers = new JB721Tier[](maxTierId);
142
+ // Count the number of included tiers.
143
+ uint256 numberOfIncludedTiers;
144
+ // Get a reference to the sorted index being iterated on, starting with the first one.
145
+ uint256 currentSortIndex = _firstSortedTierIdOf(nft, 0);
146
+ // Keep a reference to the tier being iterated on.
147
+ JBStored721Tier memory storedTier;
148
+ // Make the sorted array.
149
+ while (currentSortIndex != 0 && numberOfIncludedTiers < maxTierId) {
150
+ storedTier = _storedTierOf[nft][currentSortIndex];
151
+
152
+ // Unpack stored tier.
153
+ (bool allowOwnerMint, bool transfersPausable,,,,) = _unpackBools(storedTier.packedBools);
154
+
155
+ // Add the tier to the array being returned.
156
+ tiers[numberOfIncludedTiers++] = JB721Tier({
157
+ // forge-lint: disable-next-line(unsafe-typecast)
158
+ id: uint32(currentSortIndex),
159
+ price: storedTier.price,
160
+ remainingSupply: storedTier.remainingSupply,
161
+ initialSupply: storedTier.initialSupply,
162
+ votingUnits: storedTier.price,
163
+ reserveFrequency: storedTier.reserveFrequency,
164
+ reserveBeneficiary: reserveBeneficiaryOf(nft, currentSortIndex),
165
+ encodedIPFSUri: encodedIPFSUriOf[nft][currentSortIndex],
166
+ category: storedTier.category,
167
+ discountPercent: storedTier.discountPercent,
168
+ flags: JB721TierFlags({
169
+ allowOwnerMint: allowOwnerMint,
170
+ transfersPausable: transfersPausable,
171
+ cantBeRemoved: false,
172
+ cantIncreaseDiscountPercent: false,
173
+ cantBuyWithCredits: false
174
+ }),
175
+ splitPercent: storedTier.splitPercent,
176
+ resolvedUri: ""
177
+ });
178
+ // Set the next sort index.
179
+ currentSortIndex = _nextSortedTierIdOf(nft, currentSortIndex, maxTierId);
180
+ }
181
+ // Drop the empty tiers at the end of the array.
182
+ // The array's size is based on `maxTierIdOf`, which *might* exceed the actual number of tiers.
183
+ for (uint256 i = tiers.length - 1; i >= 0; i--) {
184
+ if (tiers[i].id == 0) {
185
+ assembly ("memory-safe") {
186
+ mstore(tiers, sub(mload(tiers), 1))
187
+ }
188
+ } else {
189
+ break;
190
+ }
191
+ }
192
+ }
193
+
194
+ // forge-lint: disable-next-line(mixed-case-function)
195
+ function ForTest_setTier(address hook, uint256 index, JBStored721Tier calldata newTier) public override {
196
+ _storedTierOf[address(hook)][index] = newTier;
197
+ }
198
+
199
+ // forge-lint: disable-next-line(mixed-case-function)
200
+ function ForTest_setTierVotingUnits(address hook, uint256 tierId, uint32 votingUnits) public override {
201
+ _tierVotingUnitsOf[address(hook)][tierId] = votingUnits;
202
+ }
203
+
204
+ // forge-lint: disable-next-line(mixed-case-function)
205
+ function ForTest_setBalanceOf(address hook, address holder, uint256 tier, uint256 balance) public override {
206
+ tierBalanceOf[address(hook)][holder][tier] = balance;
207
+ }
208
+
209
+ // forge-lint: disable-next-line(mixed-case-function)
210
+ function ForTest_setReservesMintedFor(address hook, uint256 tier, uint256 amount) public override {
211
+ numberOfReservesMintedFor[address(hook)][tier] = amount;
212
+ }
213
+
214
+ // forge-lint: disable-next-line(mixed-case-function)
215
+ function ForTest_setIsTierRemoved(address hook, uint256 tokenId) public override {
216
+ _removedTiersBitmapWordOf[hook].removeTier(tokenId);
217
+ }
218
+
219
+ // forge-lint: disable-next-line(mixed-case-function)
220
+ function ForTest_packBools(
221
+ bool allowOwnerMint,
222
+ bool transfersPausable,
223
+ bool useVotingUnits,
224
+ bool cantBeRemoved,
225
+ bool cantIncreaseDiscountPercent,
226
+ bool cantBuyWithCredits
227
+ )
228
+ public
229
+ pure
230
+ returns (uint8)
231
+ {
232
+ return _packBools(
233
+ allowOwnerMint,
234
+ transfersPausable,
235
+ useVotingUnits,
236
+ cantBeRemoved,
237
+ cantIncreaseDiscountPercent,
238
+ cantBuyWithCredits
239
+ );
240
+ }
241
+
242
+ // forge-lint: disable-next-line(mixed-case-function)
243
+ function ForTest_unpackBools(uint8 packed) public pure returns (bool, bool, bool, bool, bool, bool) {
244
+ return _unpackBools(packed);
245
+ }
246
+ }
@@ -0,0 +1,213 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity 0.8.28;
3
+
4
+ // forge-lint: disable-next-line(unaliased-plain-import)
5
+ import "@bananapus/core-v6/src/JBController.sol";
6
+ // forge-lint: disable-next-line(unaliased-plain-import)
7
+ import "@bananapus/core-v6/src/JBDirectory.sol";
8
+ // forge-lint: disable-next-line(unaliased-plain-import)
9
+ import "@bananapus/core-v6/src/JBMultiTerminal.sol";
10
+ // forge-lint: disable-next-line(unaliased-plain-import)
11
+ import "@bananapus/core-v6/src/JBFundAccessLimits.sol";
12
+ // forge-lint: disable-next-line(unaliased-plain-import)
13
+ import "@bananapus/core-v6/src/JBFeelessAddresses.sol";
14
+ // forge-lint: disable-next-line(unaliased-plain-import)
15
+ import "@bananapus/core-v6/src/JBTerminalStore.sol";
16
+ // forge-lint: disable-next-line(unaliased-plain-import)
17
+ import "@bananapus/core-v6/src/JBRulesets.sol";
18
+ // forge-lint: disable-next-line(unaliased-plain-import)
19
+ import "@bananapus/core-v6/src/JBPermissions.sol";
20
+ // forge-lint: disable-next-line(unaliased-plain-import)
21
+ import "@bananapus/core-v6/src/JBPrices.sol";
22
+ import {JBProjects} from "@bananapus/core-v6/src/JBProjects.sol";
23
+ // forge-lint: disable-next-line(unaliased-plain-import)
24
+ import "@bananapus/core-v6/src/JBSplits.sol";
25
+ // forge-lint: disable-next-line(unaliased-plain-import)
26
+ import "@bananapus/core-v6/src/JBERC20.sol";
27
+ // forge-lint: disable-next-line(unaliased-plain-import)
28
+ import "@bananapus/core-v6/src/JBTokens.sol";
29
+
30
+ // forge-lint: disable-next-line(unaliased-plain-import)
31
+ import "@bananapus/core-v6/src/structs/JBAfterPayRecordedContext.sol";
32
+ // forge-lint: disable-next-line(unaliased-plain-import)
33
+ import "@bananapus/core-v6/src/structs/JBAfterCashOutRecordedContext.sol";
34
+ // forge-lint: disable-next-line(unaliased-plain-import)
35
+ import "@bananapus/core-v6/src/structs/JBFee.sol";
36
+ // forge-lint: disable-next-line(unaliased-plain-import)
37
+ import "@bananapus/core-v6/src/structs/JBFundAccessLimitGroup.sol";
38
+ // forge-lint: disable-next-line(unaliased-plain-import)
39
+ import "@bananapus/core-v6/src/structs/JBRuleset.sol";
40
+ // forge-lint: disable-next-line(unaliased-plain-import)
41
+ import "@bananapus/core-v6/src/structs/JBRulesetConfig.sol";
42
+ // forge-lint: disable-next-line(unaliased-plain-import)
43
+ import "@bananapus/core-v6/src/structs/JBRulesetMetadata.sol";
44
+ // forge-lint: disable-next-line(unaliased-plain-import)
45
+ import "@bananapus/core-v6/src/structs/JBPermissionsData.sol";
46
+ // forge-lint: disable-next-line(unaliased-plain-import)
47
+ import "@bananapus/core-v6/src/structs/JBBeforePayRecordedContext.sol";
48
+ // forge-lint: disable-next-line(unaliased-plain-import)
49
+ import "@bananapus/core-v6/src/structs/JBBeforeCashOutRecordedContext.sol";
50
+ // forge-lint: disable-next-line(unaliased-plain-import)
51
+ import "@bananapus/core-v6/src/structs/JBSplit.sol";
52
+
53
+ // forge-lint: disable-next-line(unaliased-plain-import)
54
+ import "@bananapus/core-v6/src/interfaces/IJBTerminal.sol";
55
+ // forge-lint: disable-next-line(unaliased-plain-import)
56
+ import "@bananapus/core-v6/src/interfaces/IJBToken.sol";
57
+
58
+ // forge-lint: disable-next-line(unaliased-plain-import)
59
+ import "@bananapus/permission-ids-v6/src/JBPermissionIds.sol";
60
+ // forge-lint: disable-next-line(unaliased-plain-import)
61
+ import "@bananapus/core-v6/src/libraries/JBRulesetMetadataResolver.sol";
62
+
63
+ // forge-lint: disable-next-line(unused-import)
64
+ import {mulDiv} from "@prb/math/src/Common.sol";
65
+
66
+ // forge-lint: disable-next-line(unaliased-plain-import)
67
+ import "forge-std/Test.sol";
68
+
69
+ // forge-lint: disable-next-line(unaliased-plain-import)
70
+ import "./AccessJBLib.sol";
71
+
72
+ // forge-lint: disable-next-line(unaliased-plain-import)
73
+ import "../../src/structs/JBPayDataHookRulesetConfig.sol";
74
+ // forge-lint: disable-next-line(unaliased-plain-import)
75
+ import "../../src/structs/JBPayDataHookRulesetMetadata.sol";
76
+
77
+ /// @notice Base contract for Juicebox system tests.
78
+ /// @dev Provides common functionality, such as deploying contracts on test setup.
79
+ contract TestBaseWorkflow is Test {
80
+ //*********************************************************************//
81
+ // --------------------- internal stored properties ------------------- //
82
+ //*********************************************************************//
83
+
84
+ address internal projectOwner = address(123);
85
+ address internal beneficiary = address(69_420);
86
+ address internal caller = address(696_969);
87
+
88
+ JBPermissions internal jbPermissions;
89
+ JBProjects internal jbProjects;
90
+ JBPrices internal jbPrices;
91
+ JBDirectory internal jbDirectory;
92
+ JBRulesets internal jbRulesets;
93
+ JBTokens internal jbTokens;
94
+ JBFundAccessLimits internal jbFundAccessLimits;
95
+ JBFeelessAddresses internal jbFeelessAddresses;
96
+ JBSplits internal jbSplits;
97
+ JBController internal jbController;
98
+ JBTerminalStore internal jbTerminalStore;
99
+ JBMultiTerminal internal jbMultiTerminal;
100
+ string internal projectUri;
101
+ IJBToken internal tokenV2;
102
+
103
+ // forge-lint: disable-next-line(mixed-case-variable)
104
+ AccessJBLib internal accessJBLib;
105
+
106
+ //*********************************************************************//
107
+ // --------------------------- test setup ---------------------------- //
108
+ //*********************************************************************//
109
+
110
+ // Deploys and initializes contracts for testing.
111
+ function setUp() public virtual {
112
+ // ---- Set up project ---- //
113
+ jbPermissions = new JBPermissions(address(0));
114
+ vm.label(address(jbPermissions), "JBPermissions");
115
+
116
+ jbProjects = new JBProjects(projectOwner, address(0), address(0));
117
+ vm.label(address(jbProjects), "JBProjects");
118
+
119
+ jbDirectory = new JBDirectory(jbPermissions, jbProjects, projectOwner);
120
+ vm.label(address(jbDirectory), "JBDirectory");
121
+
122
+ jbPrices = new JBPrices(jbDirectory, jbPermissions, jbProjects, projectOwner, address(0));
123
+ vm.label(address(jbPrices), "JBPrices");
124
+
125
+ jbRulesets = new JBRulesets(jbDirectory);
126
+ vm.label(address(jbRulesets), "JBRulesets");
127
+
128
+ jbFundAccessLimits = new JBFundAccessLimits(jbDirectory);
129
+ vm.label(address(jbFundAccessLimits), "JBFundAccessLimits");
130
+
131
+ jbFeelessAddresses = new JBFeelessAddresses(address(69));
132
+ vm.label(address(jbFeelessAddresses), "JBFeelessAddresses");
133
+
134
+ jbTokens = new JBTokens(jbDirectory, new JBERC20(jbPermissions, jbProjects));
135
+ vm.label(address(jbTokens), "JBTokens");
136
+
137
+ jbSplits = new JBSplits(jbDirectory);
138
+ vm.label(address(jbSplits), "JBSplits");
139
+
140
+ jbController = new JBController(
141
+ jbDirectory,
142
+ jbFundAccessLimits,
143
+ jbPermissions,
144
+ jbPrices,
145
+ jbProjects,
146
+ jbRulesets,
147
+ jbSplits,
148
+ jbTokens,
149
+ address(0),
150
+ address(0)
151
+ );
152
+ vm.label(address(jbController), "JBController");
153
+
154
+ vm.prank(projectOwner);
155
+ jbDirectory.setIsAllowedToSetFirstController(address(jbController), true);
156
+
157
+ jbTerminalStore = new JBTerminalStore(jbDirectory, jbPrices, jbRulesets);
158
+ vm.label(address(jbTerminalStore), "JBTerminalStore");
159
+
160
+ accessJBLib = new AccessJBLib();
161
+
162
+ jbMultiTerminal = new JBMultiTerminal(
163
+ jbFeelessAddresses,
164
+ jbPermissions,
165
+ jbProjects,
166
+ jbSplits,
167
+ jbTerminalStore,
168
+ jbTokens,
169
+ IPermit2(address(0)),
170
+ address(0)
171
+ );
172
+ vm.label(address(jbMultiTerminal), "JBMultiTerminal");
173
+
174
+ projectUri = "myIPFSHash";
175
+
176
+ // ---- general setup ---- //
177
+ vm.deal(beneficiary, 100 ether);
178
+ vm.deal(projectOwner, 100 ether);
179
+ vm.deal(caller, 100 ether);
180
+
181
+ vm.label(projectOwner, "projectOwner");
182
+ vm.label(beneficiary, "beneficiary");
183
+ vm.label(caller, "caller");
184
+ }
185
+
186
+ //https://ethereum.stackexchange.com/questions/24248/how-to-calculate-an-ethereum-contracts-address-during-its-creation-using-the-so
187
+ function addressFrom(address origin, uint256 nonce) internal pure returns (address addr) {
188
+ bytes memory data;
189
+ if (nonce == 0x00) {
190
+ data = abi.encodePacked(bytes1(0xd6), bytes1(0x94), origin, bytes1(0x80));
191
+ } else if (nonce <= 0x7f) {
192
+ // forge-lint: disable-next-line(unsafe-typecast)
193
+ data = abi.encodePacked(bytes1(0xd6), bytes1(0x94), origin, uint8(nonce));
194
+ } else if (nonce <= 0xff) {
195
+ // forge-lint: disable-next-line(unsafe-typecast)
196
+ data = abi.encodePacked(bytes1(0xd7), bytes1(0x94), origin, bytes1(0x81), uint8(nonce));
197
+ } else if (nonce <= 0xffff) {
198
+ // forge-lint: disable-next-line(unsafe-typecast)
199
+ data = abi.encodePacked(bytes1(0xd8), bytes1(0x94), origin, bytes1(0x82), uint16(nonce));
200
+ } else if (nonce <= 0xffffff) {
201
+ // forge-lint: disable-next-line(unsafe-typecast)
202
+ data = abi.encodePacked(bytes1(0xd9), bytes1(0x94), origin, bytes1(0x83), uint24(nonce));
203
+ } else {
204
+ // forge-lint: disable-next-line(unsafe-typecast)
205
+ data = abi.encodePacked(bytes1(0xda), bytes1(0x94), origin, bytes1(0x84), uint32(nonce));
206
+ }
207
+ bytes32 hash = keccak256(data);
208
+ assembly ("memory-safe") {
209
+ mstore(0, hash)
210
+ addr := mload(0)
211
+ }
212
+ }
213
+ }