@bannynet/core-v6 0.0.41 → 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 CHANGED
@@ -2,13 +2,18 @@
2
2
 
3
3
  Banny Retail is an onchain avatar system for Juicebox 721 collections. A body NFT can wear outfit NFTs, use a background NFT, and resolve to a base64 JSON token URI whose image is an onchain SVG.
4
4
 
5
- Docs: <https://docs.juicebox.money>
6
- Architecture: [ARCHITECTURE.md](./ARCHITECTURE.md)
7
- User journeys: [USER_JOURNEYS.md](./USER_JOURNEYS.md)
8
- Skills: [SKILLS.md](./SKILLS.md)
9
- Risks: [RISKS.md](./RISKS.md)
10
- Administration: [ADMINISTRATION.md](./ADMINISTRATION.md)
11
- Audit instructions: [AUDIT_INSTRUCTIONS.md](./AUDIT_INSTRUCTIONS.md)
5
+
6
+ ## Documentation
7
+
8
+ - [ARCHITECTURE.md](./ARCHITECTURE.md) — system structure and contract responsibilities
9
+ - [USER_JOURNEYS.md](./USER_JOURNEYS.md) — end-to-end flows for body owners and asset holders
10
+ - [INVARIANTS.md](./INVARIANTS.md) — properties guaranteed by the resolver
11
+ - [RISKS.md](./RISKS.md) — known risks and edge cases
12
+ - [ADMINISTRATION.md](./ADMINISTRATION.md) — owner-only actions and operational levers
13
+ - [AUDIT_INSTRUCTIONS.md](./AUDIT_INSTRUCTIONS.md) — guidance for security reviewers
14
+ - [SKILLS.md](./SKILLS.md) — repo-specific gotchas and integration notes
15
+ - [STYLE_GUIDE.md](./STYLE_GUIDE.md) — coding and naming conventions
16
+ - [CHANGELOG.md](./CHANGELOG.md) — notable changes
12
17
 
13
18
  ## Overview
14
19
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bannynet/core-v6",
3
- "version": "0.0.41",
3
+ "version": "0.0.43",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
@@ -27,18 +27,18 @@
27
27
  "artifacts": "source ./.env && npx sphinx artifacts --org-id 'ea165b21-7cdc-4d7b-be59-ecdd4c26bee4' --project-name 'banny-core-v6'"
28
28
  },
29
29
  "dependencies": {
30
- "@bananapus/721-hook-v6": "^0.0.59",
31
- "@bananapus/buyback-hook-v6": "^0.0.58",
32
- "@bananapus/core-v6": "^0.0.72",
33
- "@bananapus/router-terminal-v6": "^0.0.55",
34
- "@bananapus/suckers-v6": "^0.0.60",
35
- "@croptop/core-v6": "^0.0.60",
30
+ "@bananapus/721-hook-v6": "^0.0.65",
31
+ "@bananapus/buyback-hook-v6": "^0.0.66",
32
+ "@bananapus/core-v6": "^0.0.78",
33
+ "@bananapus/router-terminal-v6": "^0.0.60",
34
+ "@bananapus/suckers-v6": "^0.0.67",
35
+ "@croptop/core-v6": "^0.0.64",
36
36
  "@openzeppelin/contracts": "5.6.1",
37
- "@rev-net/core-v6": "^0.0.78",
37
+ "@rev-net/core-v6": "^0.0.84",
38
38
  "keccak": "3.0.4"
39
39
  },
40
40
  "devDependencies": {
41
- "@bananapus/address-registry-v6": "^0.0.29",
41
+ "@bananapus/address-registry-v6": "^0.0.32",
42
42
  "@sphinx-labs/plugins": "0.33.3"
43
43
  }
44
44
  }
@@ -50,11 +50,58 @@ contract Drop1Script is Script, Sphinx {
50
50
  }
51
51
 
52
52
  function deploy() public sphinx {
53
+ // Build the Drop 1 tier set, resolving every reserve-bearing tier's beneficiary to the configured
54
+ // `reserveBeneficiary`.
55
+ (string[] memory names, bytes32[] memory svgHashes, JB721TierConfig[] memory products) =
56
+ buildDrop1Tiers(reserveBeneficiary);
57
+
58
+ // Capture the pre-existing maxTierIdOf so we can detect drift between Sphinx proposal-time simulation and
59
+ // execution. Without this guard, an authorized `ADJUST_721_TIERS` call landing between proposal and
60
+ // execution would shift our 47 new tier IDs upward, and the metadata writes below would silently target
61
+ // the wrong UPC range (or land on tiers that did not get our SVG/name data).
62
+ uint256 maxTierIdBeforeAdjust = hook.STORE().maxTierIdOf(address(hook));
63
+
64
+ hook.adjustTiers({tiersToAdd: products, tierIdsToRemove: new uint256[](0)});
65
+
66
+ // Read maxTierIdOf after adjustTiers so the value reflects our newly added tiers,
67
+ // avoiding a race condition where another transaction could change maxTierIdOf between
68
+ // the read and the adjustTiers call.
69
+ uint256 maxTierId = hook.STORE().maxTierIdOf(address(hook));
70
+
71
+ // Drift detection: our 47 tiers should occupy exactly the range (maxTierIdBeforeAdjust, maxTierId]. If
72
+ // another transaction added tiers between proposal and execution, the range no longer matches the 47-tier
73
+ // assumption and the metadata writes would target the wrong UPCs.
74
+ require(maxTierId == maxTierIdBeforeAdjust + 47, "Drop1: maxTierIdOf drift between proposal and execution");
75
+
76
+ // Build the product IDs array for the newly added tiers.
77
+ // The last 47 tier IDs correspond to this drop's tiers.
78
+ uint256[] memory productIds = new uint256[](47);
79
+ for (uint256 i; i < 47; i++) {
80
+ productIds[i] = maxTierId - 46 + i;
81
+ }
82
+
83
+ bannyverse.resolver.setSvgHashesOf({upcs: productIds, svgHashes: svgHashes});
84
+ bannyverse.resolver.setProductNames({upcs: productIds, names: names});
85
+ }
86
+
87
+ /// @notice Builds the Drop 1 tier set: product names, SVG hashes, and tier configs.
88
+ /// @dev Tiers must be sorted by category ascending, and any tier with a non-zero `reserveFrequency` must have a
89
+ /// resolvable reserve beneficiary at add time. The first reserve-bearing tier sets the hook's default reserve
90
+ /// beneficiary (via `useReserveBeneficiaryAsDefault`) so that every later reserve-bearing tier inherits it.
91
+ /// @param reserveBeneficiary_ The address that receives reserve NFTs for every reserve-bearing tier in the drop.
92
+ /// @return names The product name for each tier, indexed to `products`.
93
+ /// @return svgHashes The SVG content hash for each tier, indexed to `products`.
94
+ /// @return products The tier configs to add.
95
+ function buildDrop1Tiers(address reserveBeneficiary_)
96
+ public
97
+ pure
98
+ returns (string[] memory names, bytes32[] memory svgHashes, JB721TierConfig[] memory products)
99
+ {
53
100
  uint256 decimals = 18;
54
101
 
55
- string[] memory names = new string[](47);
56
- bytes32[] memory svgHashes = new bytes32[](47);
57
- JB721TierConfig[] memory products = new JB721TierConfig[](47);
102
+ names = new string[](47);
103
+ svgHashes = new bytes32[](47);
104
+ products = new JB721TierConfig[](47);
58
105
 
59
106
  // Desk
60
107
  names[0] = "Work Station";
@@ -153,6 +200,10 @@ contract Drop1Script is Script, Sphinx {
153
200
  splits: new JBSplit[](0)
154
201
  });
155
202
  // Block chain
203
+ // This is the first reserve-bearing tier in the drop (sorted by category ascending), so it establishes the
204
+ // hook's default reserve beneficiary. Setting it here means every later reserve-bearing tier can leave
205
+ // `reserveBeneficiary` as `address(0)` and inherit this default at add time, and the tiers add in one pass
206
+ // without a missing-beneficiary revert.
156
207
  names[4] = "Block Chain";
157
208
  svgHashes[4] = bytes32(0x5e609d387ea091bc8884a753ddd28dd43b8ed1243b29de6e9354ef1ab109a0b9);
158
209
  products[4] = JB721TierConfig({
@@ -160,13 +211,13 @@ contract Drop1Script is Script, Sphinx {
160
211
  initialSupply: 12,
161
212
  votingUnits: 0,
162
213
  reserveFrequency: 12,
163
- reserveBeneficiary: address(0),
214
+ reserveBeneficiary: reserveBeneficiary_,
164
215
  encodedIpfsUri: bytes32(0xef6478be50575bade53e7ce4c9fb5b399643bcabed94f2111afb63e97fb9fd44),
165
216
  category: 3,
166
217
  discountPercent: 0,
167
218
  flags: JB721TierConfigFlags({
168
219
  allowOwnerMint: true,
169
- useReserveBeneficiaryAsDefault: false,
220
+ useReserveBeneficiaryAsDefault: true,
170
221
  transfersPausable: false,
171
222
  useVotingUnits: false,
172
223
  cantBeRemoved: false,
@@ -232,7 +283,7 @@ contract Drop1Script is Script, Sphinx {
232
283
  initialSupply: 100,
233
284
  votingUnits: 0,
234
285
  reserveFrequency: 25,
235
- reserveBeneficiary: reserveBeneficiary,
286
+ reserveBeneficiary: reserveBeneficiary_,
236
287
  encodedIpfsUri: bytes32(0xf01423f9dae3de4adc7e372e6902a351e2c6193a385dde90f5baf37165914831),
237
288
  category: 6,
238
289
  discountPercent: 0,
@@ -1184,33 +1235,5 @@ contract Drop1Script is Script, Sphinx {
1184
1235
  splitPercent: 0,
1185
1236
  splits: new JBSplit[](0)
1186
1237
  });
1187
-
1188
- // Capture the pre-existing maxTierIdOf so we can detect drift between Sphinx proposal-time simulation and
1189
- // execution. Without this guard, an authorized `ADJUST_721_TIERS` call landing between proposal and
1190
- // execution would shift our 47 new tier IDs upward, and the metadata writes below would silently target
1191
- // the wrong UPC range (or land on tiers that did not get our SVG/name data).
1192
- uint256 maxTierIdBeforeAdjust = hook.STORE().maxTierIdOf(address(hook));
1193
-
1194
- hook.adjustTiers({tiersToAdd: products, tierIdsToRemove: new uint256[](0)});
1195
-
1196
- // Read maxTierIdOf after adjustTiers so the value reflects our newly added tiers,
1197
- // avoiding a race condition where another transaction could change maxTierIdOf between
1198
- // the read and the adjustTiers call.
1199
- uint256 maxTierId = hook.STORE().maxTierIdOf(address(hook));
1200
-
1201
- // Drift detection: our 47 tiers should occupy exactly the range (maxTierIdBeforeAdjust, maxTierId]. If
1202
- // another transaction added tiers between proposal and execution, the range no longer matches the 47-tier
1203
- // assumption and the metadata writes would target the wrong UPCs.
1204
- require(maxTierId == maxTierIdBeforeAdjust + 47, "Drop1: maxTierIdOf drift between proposal and execution");
1205
-
1206
- // Build the product IDs array for the newly added tiers.
1207
- // The last 47 tier IDs correspond to this drop's tiers.
1208
- uint256[] memory productIds = new uint256[](47);
1209
- for (uint256 i; i < 47; i++) {
1210
- productIds[i] = maxTierId - 46 + i;
1211
- }
1212
-
1213
- bannyverse.resolver.setSvgHashesOf({upcs: productIds, svgHashes: svgHashes});
1214
- bannyverse.resolver.setProductNames({upcs: productIds, names: names});
1215
1238
  }
1216
1239
  }