@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 +12 -7
- package/package.json +9 -9
- package/script/Drop1.s.sol +57 -34
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
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
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.
|
|
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.
|
|
31
|
-
"@bananapus/buyback-hook-v6": "^0.0.
|
|
32
|
-
"@bananapus/core-v6": "^0.0.
|
|
33
|
-
"@bananapus/router-terminal-v6": "^0.0.
|
|
34
|
-
"@bananapus/suckers-v6": "^0.0.
|
|
35
|
-
"@croptop/core-v6": "^0.0.
|
|
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.
|
|
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.
|
|
41
|
+
"@bananapus/address-registry-v6": "^0.0.32",
|
|
42
42
|
"@sphinx-labs/plugins": "0.33.3"
|
|
43
43
|
}
|
|
44
44
|
}
|
package/script/Drop1.s.sol
CHANGED
|
@@ -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
|
-
|
|
56
|
-
|
|
57
|
-
|
|
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:
|
|
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:
|
|
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:
|
|
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
|
}
|