@bananapus/721-hook-v6 0.0.35 → 0.0.37

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 (38) hide show
  1. package/ADMINISTRATION.md +49 -163
  2. package/ARCHITECTURE.md +71 -49
  3. package/AUDIT_INSTRUCTIONS.md +47 -84
  4. package/README.md +40 -28
  5. package/RISKS.md +85 -86
  6. package/SKILLS.md +17 -16
  7. package/USER_JOURNEYS.md +85 -62
  8. package/foundry.toml +2 -0
  9. package/package.json +1 -1
  10. package/references/operations.md +7 -3
  11. package/references/runtime.md +5 -4
  12. package/src/JB721CheckpointsDeployer.sol +2 -0
  13. package/src/JB721TiersHook.sol +0 -2
  14. package/src/JB721TiersHookProjectDeployer.sol +0 -1
  15. package/src/JB721TiersHookStore.sol +1 -2
  16. package/src/abstract/JB721Hook.sol +0 -1
  17. package/src/interfaces/IJB721CheckpointsDeployer.sol +3 -0
  18. package/src/interfaces/IJB721TiersHook.sol +0 -2
  19. package/src/interfaces/IJB721TiersHookStore.sol +1 -1
  20. package/src/libraries/JB721Constants.sol +0 -1
  21. package/src/structs/JB721InitTiersConfig.sol +0 -1
  22. package/src/structs/JB721Tier.sol +0 -2
  23. package/src/structs/JB721TierConfig.sol +0 -2
  24. package/src/structs/JB721TierConfigFlags.sol +0 -1
  25. package/src/structs/JB721TierFlags.sol +0 -1
  26. package/src/structs/JB721TiersHookFlags.sol +0 -1
  27. package/src/structs/JB721TiersMintReservesConfig.sol +0 -1
  28. package/src/structs/JB721TiersRulesetMetadata.sol +0 -1
  29. package/src/structs/JB721TiersSetDiscountPercentConfig.sol +0 -1
  30. package/src/structs/JBBitmapWord.sol +0 -1
  31. package/src/structs/JBDeploy721TiersHookConfig.sol +0 -1
  32. package/src/structs/JBLaunchProjectConfig.sol +0 -1
  33. package/src/structs/JBLaunchRulesetsConfig.sol +0 -1
  34. package/src/structs/JBPayDataHookRulesetConfig.sol +0 -1
  35. package/src/structs/JBPayDataHookRulesetMetadata.sol +0 -1
  36. package/src/structs/JBQueueRulesetsConfig.sol +0 -1
  37. package/src/structs/JBStored721Tier.sol +0 -1
  38. package/test/unit/JB721CheckpointsDeployer_AccessControl.t.sol +116 -0
package/USER_JOURNEYS.md CHANGED
@@ -1,98 +1,121 @@
1
1
  # User Journeys
2
2
 
3
- ## Who This Repo Serves
3
+ ## Repo Purpose
4
4
 
5
- - project owners selling or rewarding supporters with tiered NFTs
6
- - operators managing tier supply, pricing, reserves, and ruleset-aware hook behavior
7
- - supporters minting or cashing out tier positions through normal Juicebox flows
8
- - integrators composing custom token URI resolvers on top of the standard 721 hook
5
+ This repo adds tiered NFT logic to Juicebox payment and cash-out flows. It owns tier pricing, reserves, and NFT lifecycle state. It does not own project-specific artwork or game logic.
9
6
 
10
- ## Journey 1: Add A Tiered 721 Hook To An Existing Project
7
+ ## Primary Actors
11
8
 
12
- **Starting state:** the project already exists in Juicebox and needs tiered NFT issuance without relaunching.
9
+ - projects that want priced NFT tiers in their Juicebox flow
10
+ - operators managing tier configuration and hook permissions
11
+ - holders minting, transferring, and cashing out tiered NFTs
12
+ - auditors reviewing tier accounting, reserve behavior, and deployer wiring
13
13
 
14
- **Success:** a hook clone is deployed, initialized, and attached to the project's ruleset metadata.
14
+ ## Key Surfaces
15
15
 
16
- **Flow**
17
- 1. Use `JB721TiersHookDeployer` to clone a hook for the target project.
18
- 2. Define tier config, reserve behavior, token URI resolver, and per-ruleset flags.
19
- 3. Queue or install ruleset metadata that tells the project when the hook should participate in pay and cash-out flows.
20
- 4. Future payments into the project can now mint tiers under the configured constraints.
16
+ - `JB721TiersHook`: runtime 721 hook behavior
17
+ - `JB721TiersHookStore`: tier accounting and supply state
18
+ - `JB721TiersHookDeployer` and `JB721TiersHookProjectDeployer`: wiring surfaces
19
+ - token URI resolver contracts in downstream repos: presentation layer
21
20
 
22
- ## Journey 2: Launch A New Project With A 721 Hook Already Wired In
21
+ ## Journey 1: Launch A Project With A Tiered NFT Hook
23
22
 
24
- **Starting state:** the product wants its project treasury and NFT logic created in one operation.
23
+ **Actor:** project operator or deployer.
25
24
 
26
- **Success:** the project launches with the hook, terminals, and initial tiers already aligned.
25
+ **Intent:** attach tiered NFT issuance to a project from the start.
27
26
 
28
- **Flow**
29
- 1. Use `JB721TiersHookProjectDeployer` with launch config, rulesets, and hook config.
30
- 2. The deployer launches the project through the core protocol and deploys the hook in the same packaged flow.
31
- 3. The initial ruleset metadata points at the newly created hook so there is no post-launch rewiring gap.
32
- 4. The project starts life as a tiered 721 project instead of becoming one later.
27
+ **Preconditions**
28
+ - the project knows its tier structure and hook expectations
29
+ - the deployer path matches whether the project already exists
33
30
 
34
- ## Journey 3: Mint Specific Tiers Through A Payment
31
+ **Main Flow**
32
+ 1. Deploy a hook clone or launch a project with the hook already attached.
33
+ 2. Configure tier data, hook metadata, and resolver expectations.
34
+ 3. Transfer hook ownership into the intended project control surface.
35
35
 
36
- **Starting state:** the project has live tiers and the payer knows which tiers they want.
36
+ **Failure Modes**
37
+ - wrong hook wiring at launch
38
+ - wrong resolver assumptions
39
+ - teams treat deployer convenience as proof that runtime economics are correct
37
40
 
38
- **Success:** the treasury receives funds and the beneficiary receives the intended NFT tiers plus any accompanying project-token behavior.
41
+ **Postconditions**
42
+ - the project has a tiered NFT hook wired into its Juicebox flow
39
43
 
40
- **Flow**
41
- 1. The payer submits a payment with metadata encoding the desired tier selections.
42
- 2. `JB721TiersHook` validates tier availability, quantity rules, discounts, category constraints, and any ruleset flags affecting minting.
43
- 3. `JB721TiersHookStore` updates supply and reserve accounting.
44
- 4. The hook mints the correct NFTs and the underlying terminal completes treasury accounting.
44
+ ## Journey 2: Pay And Mint Tiered NFTs
45
45
 
46
- **Failure cases that matter:** sold-out tiers, bad metadata, cross-currency pricing mistakes, paused pay-hook behavior, and split-routing edge cases when part of the payment should bypass normal minting assumptions.
46
+ **Actor:** payer or integration acting for a payer.
47
47
 
48
- ## Journey 4: Mint Reserves And Operate Tier Inventory Over Time
48
+ **Intent:** mint NFTs from configured tiers while preserving the project's terminal flow.
49
49
 
50
- **Starting state:** the collection is live and the owner needs to manage what exists for future minters versus reserve recipients.
50
+ **Preconditions**
51
+ - the project has active tiers
52
+ - payment metadata correctly names the intended tiers
51
53
 
52
- **Success:** reserves, new tiers, removed tiers, and editable fields evolve without corrupting ownership or supply history.
54
+ **Main Flow**
55
+ 1. A payment reaches the hook through the terminal.
56
+ 2. The hook decodes tier selection and records mint state in the store.
57
+ 3. NFTs mint, reserve implications update, and any split routing is applied.
53
58
 
54
- **Flow**
55
- 1. Authorized operators use the hook's tier-management surfaces to add, remove, or adjust tiers.
56
- 2. Reserve minting uses the configured reserve frequency and reserve beneficiary settings instead of ad hoc treasury actions.
57
- 3. The store keeps historical tier state coherent so existing token IDs continue to resolve correctly.
58
- 4. Downstream products such as Croptop, Banny, and Revnets can continue assuming stable tier semantics.
59
+ **Failure Modes**
60
+ - malformed metadata
61
+ - currency mismatch or missing pricing support
62
+ - splits or discounts behave differently than the integration expected
59
63
 
60
- ## Journey 5: Let Holders Cash Out Tier Positions
64
+ **Postconditions**
65
+ - the payer or beneficiary receives the intended NFT tiers and tier state updates
61
66
 
62
- **Starting state:** a holder owns one or more NFTs from a hook-enabled project and the active ruleset allows surplus-backed exits.
67
+ ## Journey 3: Mint Or Release Reserve NFTs
63
68
 
64
- **Success:** the holder burns the intended tier exposure and receives the correct reclaim value through the core terminal.
69
+ **Actor:** reserve beneficiary, operator, or any caller using the reserve path.
65
70
 
66
- **Flow**
67
- 1. The holder calls the project's cash-out path on the terminal.
68
- 2. The hook participates in the cash-out calculation so tier-specific weight and store state are reflected correctly.
69
- 3. The terminal settles reclaim value and the NFT position is burned or otherwise marked as consumed by the exit path.
71
+ **Intent:** realize pending reserves under the configured reserve rules.
70
72
 
71
- **Edge conditions that change user experience:** ERC-20 cash-out surfaces, tier splits, reserve accounting drift, broken downstream terminals, and projects that use the hook for metadata only versus economically binding flows.
73
+ **Preconditions**
74
+ - the relevant tiers have reserve logic enabled
75
+ - the ruleset does not pause pending reserve minting
72
76
 
73
- ## Journey 6: Compose A Custom Product On Top Of The Standard Hook
77
+ **Main Flow**
78
+ 1. Eligible reserve amounts accumulate as mint activity happens.
79
+ 2. A caller triggers reserve minting for pending tiers.
80
+ 3. The store moves reserve state forward and NFTs mint to the configured reserve beneficiary.
74
81
 
75
- **Starting state:** the team wants product-specific rendering or business rules but does not want to fork tier issuance.
82
+ **Failure Modes**
83
+ - teams misunderstand that reserve minting timing is not owner-exclusive
84
+ - reserve assumptions drift from actual tier settings
76
85
 
77
- **Success:** the product resolver or wrapper composes with the hook instead of reimplementing pricing, tier accounting, and treasury logic.
86
+ **Postconditions**
87
+ - pending reserves mint according to tier configuration
78
88
 
79
- **Flow**
80
- 1. Plug a custom resolver into the hook for metadata and product-specific presentation.
81
- 2. Keep collection-specific behavior in the downstream repo while leaving pay, reserve, and cash-out semantics in this repo.
82
- 3. Audit hook-store interactions here first, then audit the downstream resolver or wrapper.
89
+ ## Journey 4: Cash Out Tiered NFTs
83
90
 
84
- ## Journey 7: Mint NFTs To The Correct Beneficiary During Cross-Chain Payments
91
+ **Actor:** NFT holder.
85
92
 
86
- **Starting state:** a sucker pays the project on behalf of a remote user via `payRemote`, and the 721 hook needs to mint NFTs and accrue credits to the real user instead of the sucker contract.
93
+ **Intent:** redeem tiered NFT exposure through the terminal cash-out path.
87
94
 
88
- **Success:** NFTs mint to and pay credits accrue to the real remote user.
95
+ **Preconditions**
96
+ - the holder owns valid NFTs
97
+ - the hook is active for the cash-out path
89
98
 
90
- **Flow**
91
- 1. The sucker calls `terminal.pay()` with itself as both payer and beneficiary, embedding the real user's address in the `JB_RELAY_BENEFICIARY` metadata key.
92
- 2. `_mintAndUpdateCredits` detects that `payer == beneficiary` and finds relay-beneficiary metadata.
93
- 3. All NFT minting and credit accounting uses the resolved relay beneficiary instead of the sucker address.
99
+ **Main Flow**
100
+ 1. The holder requests a cash out with NFT-specific metadata.
101
+ 2. The hook burns the selected NFTs and records the burn in the store.
102
+ 3. The terminal completes reclaim logic using the hook-aware cash-out surface.
103
+
104
+ **Failure Modes**
105
+ - integrations mix fungible-token and NFT cash-out assumptions
106
+ - pending reserves or discounts are misunderstood in value calculations
107
+ - token IDs are invalid or already burned
108
+
109
+ **Postconditions**
110
+ - NFTs burn and reclaim value follows the intended tier model
111
+
112
+ ## Trust Boundaries
113
+
114
+ - this repo trusts core terminals, directory checks, and pricing surfaces from `nana-core-v6`
115
+ - metadata resolvers are outside this repo but still affect user-visible trust
116
+ - the store is the main source of truth for tier lifecycle state
94
117
 
95
118
  ## Hand-Offs
96
119
 
97
- - Use [nana-core-v6](../nana-core-v6/USER_JOURNEYS.md) for the treasury, ruleset, and permission surfaces the hook plugs into.
98
- - Use [banny-retail-v6](../banny-retail-v6/USER_JOURNEYS.md), [croptop-core-v6](../croptop-core-v6/USER_JOURNEYS.md), and [revnet-core-v6](../revnet-core-v6/USER_JOURNEYS.md) for product layers built on this hook.
120
+ - Use [nana-core-v6](../nana-core-v6/USER_JOURNEYS.md) for the underlying terminal and accounting behavior.
121
+ - Use the downstream resolver repo when the question is about project-specific metadata or rendering.
package/foundry.toml CHANGED
@@ -13,6 +13,8 @@ runs = 1024
13
13
  depth = 100
14
14
  fail_on_revert = false
15
15
 
16
+ [lint]
17
+ exclude_lints = ["pascal-case-struct", "mixed-case-variable"]
16
18
  [fmt]
17
19
  number_underscore = "thousands"
18
20
  multiline_func_header = "all"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bananapus/721-hook-v6",
3
- "version": "0.0.35",
3
+ "version": "0.0.37",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
@@ -9,7 +9,9 @@
9
9
  ## Change Checklist
10
10
 
11
11
  - If you edit hook initialization, verify deployer config structs and project-launch helpers still encode the same assumptions.
12
- - If you edit tier config or metadata behavior, inspect [`src/structs/`](../src/structs/) and the corresponding interfaces in [`src/interfaces/`](../src/interfaces/).
12
+ - If you edit tier config or metadata behavior, inspect the corresponding structs and interfaces in `src/structs/` and `src/interfaces/`.
13
+ - If you edit reserve behavior, verify pending reserve counts, default reserve beneficiary semantics, and cash-out denominator effects together.
14
+ - If you edit discount behavior, verify mint price and cash-out weight separately. They are intentionally not the same quantity.
13
15
  - If you touch permissions, verify the caller path and permission constants still line up with the downstream ecosystem package that defines them.
14
16
  - If you touch URI behavior, confirm whether the issue belongs in this repo or in a downstream resolver contract that the hook calls.
15
17
 
@@ -24,5 +26,7 @@
24
26
 
25
27
  - [`test/Fork.t.sol`](../test/Fork.t.sol) for live-integration assumptions.
26
28
  - [`test/TestAuditGaps.sol`](../test/TestAuditGaps.sol) for known edge cases the repo authors considered worth pinning down.
27
- - [`test/unit/`](../test/unit/) when you need a narrow function-level proof before editing a broad runtime path.
28
- - [`script/helpers/`](../script/helpers/) when a deployment or launch question is really about config assembly rather than contract behavior.
29
+ - [`test/TestCheckpoints.t.sol`](../test/TestCheckpoints.t.sol) when you need a narrow function-level proof before editing a broad runtime path.
30
+ - [`test/invariants/TierLifecycleInvariant.t.sol`](../test/invariants/TierLifecycleInvariant.t.sol) and [`test/invariants/TieredHookStoreInvariant.t.sol`](../test/invariants/TieredHookStoreInvariant.t.sol) when a local patch may have broken store-level relationships.
31
+ - [`test/audit/CodexRetroactiveReserveBeneficiaryDilution.t.sol`](../test/audit/CodexRetroactiveReserveBeneficiaryDilution.t.sol) when reserve-beneficiary or pending-reserve behavior changes.
32
+ - [`script/Deploy.s.sol`](../script/Deploy.s.sol) when a deployment or launch question is really about config assembly rather than contract behavior.
@@ -22,11 +22,12 @@
22
22
  - Discount behavior: price discounts affect mint eligibility but cash-out weight still tracks the original tier price. Do not conflate the two.
23
23
  - Voting units: verify whether a tier uses explicit voting units or falls back to price-based voting power before changing governance-facing math.
24
24
  - Tier removal and cleanup: removing tiers is not the same as cleaning the sorted tier list. Storage cleanup behavior matters.
25
+ - Default reserve beneficiary changes: they affect which tiers count pending reserves unless a tier-specific beneficiary overrides it. That is an economic change, not just an admin update.
25
26
 
26
27
  ## Tests To Trust First
27
28
 
28
- - [`test/invariants/`](../test/invariants/) for broad accounting invariants.
29
- - [`test/E2E/`](../test/E2E/) for launch and end-to-end payment flows.
30
- - [`test/regression/`](../test/regression/) for previously broken edge cases.
29
+ - [`test/Fork.t.sol`](../test/Fork.t.sol) for launch and live integration flows.
31
30
  - [`test/TestVotingUnitsLifecycle.t.sol`](../test/TestVotingUnitsLifecycle.t.sol) for voting-unit lifecycle behavior.
32
- - [`test/TestSafeTransferReentrancy.t.sol`](../test/TestSafeTransferReentrancy.t.sol) and [`test/721HookAttacks.t.sol`](../test/721HookAttacks.t.sol) for reentrancy and attack-surface checks.
31
+ - [`test/TestCheckpoints.t.sol`](../test/TestCheckpoints.t.sol) for checkpoint/module behavior.
32
+ - [`test/invariants/TierLifecycleInvariant.t.sol`](../test/invariants/TierLifecycleInvariant.t.sol) and [`test/invariants/TieredHookStoreInvariant.t.sol`](../test/invariants/TieredHookStoreInvariant.t.sol) for store-level lifecycle invariants.
33
+ - [`test/TestSafeTransferReentrancy.t.sol`](../test/TestSafeTransferReentrancy.t.sol), [`test/721HookAttacks.t.sol`](../test/721HookAttacks.t.sol), [`test/audit/CodexRetroactiveReserveBeneficiaryDilution.t.sol`](../test/audit/CodexRetroactiveReserveBeneficiaryDilution.t.sol), and [`test/TestAuditGaps.sol`](../test/TestAuditGaps.sol) for reentrancy and attack-surface checks.
@@ -37,6 +37,8 @@ contract JB721CheckpointsDeployer is IJB721CheckpointsDeployer {
37
37
  /// @param store The store that holds tier data for the hook's NFTs.
38
38
  /// @return module The newly deployed and initialized checkpoint module.
39
39
  function deploy(address hook, IJB721TiersHookStore store) external override returns (IJB721Checkpoints module) {
40
+ if (msg.sender != hook) revert JB721CheckpointsDeployer_Unauthorized();
41
+
40
42
  module = IJB721Checkpoints(
41
43
  LibClone.cloneDeterministic({implementation: IMPLEMENTATION, salt: bytes32(uint256(uint160(hook)))})
42
44
  );
@@ -457,9 +457,7 @@ contract JB721TiersHook is JBOwnable, ERC2771Context, JB721Hook, IJB721TiersHook
457
457
  string calldata baseUri,
458
458
  string calldata contractUri,
459
459
  IJB721TokenUriResolver tokenUriResolver,
460
- // forge-lint: disable-next-line(mixed-case-variable)
461
460
  uint256 encodedIPFSUriTierId,
462
- // forge-lint: disable-next-line(mixed-case-variable)
463
461
  bytes32 encodedIPFSUri
464
462
  )
465
463
  external
@@ -124,7 +124,6 @@ contract JB721TiersHookProjectDeployer is ERC2771Context, JBPermissioned, IJB721
124
124
  returns (uint256 rulesetId, IJB721TiersHook hook)
125
125
  {
126
126
  // Get the project's projects contract.
127
- // forge-lint: disable-next-line(mixed-case-variable)
128
127
  IJBProjects PROJECTS = DIRECTORY.PROJECTS();
129
128
 
130
129
  // Enforce permissions.
@@ -66,7 +66,6 @@ contract JB721TiersHookStore is IJB721TiersHookStore {
66
66
  /// @custom:param hook The 721 contract that the tier belongs to.
67
67
  /// @custom:param tierId The ID of the tier to get the encoded IPFS URI of.
68
68
  /// @custom:returns The encoded IPFS URI.
69
- // forge-lint: disable-next-line(mixed-case-variable)
70
69
  mapping(address hook => mapping(uint256 tierId => bytes32)) public override encodedIPFSUriOf;
71
70
 
72
71
  /// @notice Returns the largest tier ID currently used on the provided 721 contract.
@@ -1344,7 +1343,7 @@ contract JB721TiersHookStore is IJB721TiersHookStore {
1344
1343
  /// @notice Record a new encoded IPFS URI for a tier.
1345
1344
  /// @param tierId The ID of the tier to set the encoded IPFS URI of.
1346
1345
  /// @param encodedIPFSUri The encoded IPFS URI to set for the tier.
1347
- // forge-lint: disable-next-line(mixed-case-function, mixed-case-variable)
1346
+ // forge-lint: disable-next-line(mixed-case-function)
1348
1347
  function recordSetEncodedIPFSUriOf(uint256 tierId, bytes32 encodedIPFSUri) external override {
1349
1348
  encodedIPFSUriOf[msg.sender][tierId] = encodedIPFSUri;
1350
1349
  }
@@ -49,7 +49,6 @@ abstract contract JB721Hook is ERC721, IJB721Hook {
49
49
  //*********************************************************************//
50
50
 
51
51
  /// @notice The ID of the project that this contract is associated with.
52
- // forge-lint: disable-next-line(mixed-case-variable)
53
52
  uint256 public override PROJECT_ID;
54
53
 
55
54
  //*********************************************************************//
@@ -6,6 +6,9 @@ import {IJB721TiersHookStore} from "./IJB721TiersHookStore.sol";
6
6
 
7
7
  /// @notice Deploys JB721Checkpoints clones for JB721TiersHook instances.
8
8
  interface IJB721CheckpointsDeployer {
9
+ /// @notice Thrown when the caller is not the hook that the checkpoint module is being deployed for.
10
+ error JB721CheckpointsDeployer_Unauthorized();
11
+
9
12
  /// @notice The implementation contract that clones are based on.
10
13
  /// @return The implementation address.
11
14
  // forge-lint: disable-next-line(mixed-case-function)
@@ -234,9 +234,7 @@ interface IJB721TiersHook is IJB721Hook {
234
234
  string calldata baseUri,
235
235
  string calldata contractUri,
236
236
  IJB721TokenUriResolver tokenUriResolver,
237
- // forge-lint: disable-next-line(mixed-case-variable)
238
237
  uint256 encodedIPFSUriTierId,
239
- // forge-lint: disable-next-line(mixed-case-variable)
240
238
  bytes32 encodedIPFSUri
241
239
  )
242
240
  external;
@@ -247,7 +247,7 @@ interface IJB721TiersHookStore {
247
247
  /// @notice Record a new encoded IPFS URI for a tier.
248
248
  /// @param tierId The ID of the tier to set the encoded IPFS URI of.
249
249
  /// @param encodedIPFSUri The encoded IPFS URI to set for the tier.
250
- // forge-lint: disable-next-line(mixed-case-function, mixed-case-variable)
250
+ // forge-lint: disable-next-line(mixed-case-function)
251
251
  function recordSetEncodedIPFSUriOf(uint256 tierId, bytes32 encodedIPFSUri) external;
252
252
 
253
253
  /// @notice Record a newly set token URI resolver.
@@ -8,6 +8,5 @@ library JB721Constants {
8
8
  /// @notice The metadata ID used to identify the 721 beneficiary entry in payment metadata.
9
9
  /// @dev When a sucker pays on behalf of a remote user, the real user's address is embedded under this key
10
10
  /// so NFTs mint to the correct recipient.
11
- // forge-lint: disable-next-line(mixed-case-variable)
12
11
  bytes4 public constant BENEFICIARY_METADATA_ID = bytes4(keccak256("JB_721_BENEFICIARY"));
13
12
  }
@@ -8,7 +8,6 @@ import {JB721TierConfig} from "./JB721TierConfig.sol";
8
8
  /// @custom:member tiers The tiers to initialize the hook with.
9
9
  /// @custom:member currency The currency that the tier prices are denoted in. See `JBPrices`.
10
10
  /// @custom:member decimals The number of decimals in the fixed point tier prices.
11
- // forge-lint: disable-next-line(pascal-case-struct)
12
11
  struct JB721InitTiersConfig {
13
12
  JB721TierConfig[] tiers;
14
13
  uint32 currency;
@@ -21,7 +21,6 @@ import {JB721TierFlags} from "./JB721TierFlags.sol";
21
21
  /// an NFT from this tier is minted. Out of `JBConstants.SPLITS_TOTAL_PERCENT`.
22
22
  /// @custom:member resolvedUri A resolved token URI for NFTs in this tier. Only available if the NFT this tier belongs
23
23
  /// to has a resolver.
24
- // forge-lint: disable-next-line(pascal-case-struct)
25
24
  struct JB721Tier {
26
25
  uint32 id;
27
26
  uint104 price;
@@ -30,7 +29,6 @@ struct JB721Tier {
30
29
  uint104 votingUnits;
31
30
  uint16 reserveFrequency;
32
31
  address reserveBeneficiary;
33
- // forge-lint: disable-next-line(mixed-case-variable)
34
32
  bytes32 encodedIPFSUri;
35
33
  uint24 category;
36
34
  uint8 discountPercent;
@@ -23,14 +23,12 @@ import {JB721TierConfigFlags} from "./JB721TierConfigFlags.sol";
23
23
  /// an NFT from this tier is minted. Out of `JBConstants.SPLITS_TOTAL_PERCENT`.
24
24
  /// @custom:member splits The splits to use for this tier's split group. These define where the split portion of the
25
25
  /// tier's price gets routed when an NFT from this tier is minted.
26
- // forge-lint: disable-next-line(pascal-case-struct)
27
26
  struct JB721TierConfig {
28
27
  uint104 price;
29
28
  uint32 initialSupply;
30
29
  uint32 votingUnits;
31
30
  uint16 reserveFrequency;
32
31
  address reserveBeneficiary;
33
- // forge-lint: disable-next-line(mixed-case-variable)
34
32
  bytes32 encodedIPFSUri;
35
33
  uint24 category;
36
34
  uint8 discountPercent;
@@ -14,7 +14,6 @@ pragma solidity ^0.8.0;
14
14
  /// @custom:member cantIncreaseDiscountPercent If the tier cannot have its discount increased.
15
15
  /// @custom:member cantBuyWithCredits If true, this tier cannot be purchased using accumulated pay credits. Only fresh
16
16
  /// payment value counts toward this tier's price.
17
- // forge-lint: disable-next-line(pascal-case-struct)
18
17
  struct JB721TierConfigFlags {
19
18
  bool allowOwnerMint;
20
19
  bool useReserveBeneficiaryAsDefault;
@@ -7,7 +7,6 @@ pragma solidity ^0.8.0;
7
7
  /// @custom:member cantBeRemoved A boolean indicating whether attempts to remove this tier will revert.
8
8
  /// @custom:member cantIncreaseDiscountPercent If the tier cannot have its discount increased.
9
9
  /// @custom:member cantBuyWithCredits If true, this tier cannot be purchased using accumulated pay credits.
10
- // forge-lint: disable-next-line(pascal-case-struct)
11
10
  struct JB721TierFlags {
12
11
  bool allowOwnerMint;
13
12
  bool transfersPausable;
@@ -11,7 +11,6 @@ pragma solidity ^0.8.0;
11
11
  /// the NFTs being minted will revert.
12
12
  /// @custom:member issueTokensForSplits A boolean indicating whether payers receive token credit for the portion of
13
13
  /// their payment that is routed to tier splits. When false (default), weight is reduced proportionally.
14
- // forge-lint: disable-next-line(pascal-case-struct)
15
14
  struct JB721TiersHookFlags {
16
15
  bool noNewTiersWithReserves;
17
16
  bool noNewTiersWithVotes;
@@ -3,7 +3,6 @@ pragma solidity ^0.8.0;
3
3
 
4
4
  /// @custom:member tierId The ID of the tier to mint from.
5
5
  /// @custom:member count The number of NFTs to mint from that tier.
6
- // forge-lint: disable-next-line(pascal-case-struct)
7
6
  struct JB721TiersMintReservesConfig {
8
7
  uint32 tierId;
9
8
  uint16 count;
@@ -6,7 +6,6 @@ pragma solidity ^0.8.0;
6
6
  /// @custom:member pauseTransfers A boolean indicating whether NFT transfers are paused during this ruleset.
7
7
  /// @custom:member pauseMintPendingReserves A boolean indicating whether pending/outstanding NFT reserves can be minted
8
8
  /// during this ruleset.
9
- // forge-lint: disable-next-line(pascal-case-struct)
10
9
  struct JB721TiersRulesetMetadata {
11
10
  bool pauseTransfers;
12
11
  bool pauseMintPendingReserves;
@@ -3,7 +3,6 @@ pragma solidity ^0.8.0;
3
3
 
4
4
  /// @custom:member tierId The ID of the tier to set the discount percent for.
5
5
  /// @custom:member discountPercent The discount percent to set for the tier.
6
- // forge-lint: disable-next-line(pascal-case-struct)
7
6
  struct JB721TiersSetDiscountPercentConfig {
8
7
  uint32 tierId;
9
8
  uint16 discountPercent;
@@ -5,7 +5,6 @@ pragma solidity ^0.8.0;
5
5
  /// `JBBitmap` matrix is a "word".
6
6
  /// @custom:member The information stored at the index.
7
7
  /// @custom:member The index.
8
- // forge-lint: disable-next-line(pascal-case-struct)
9
8
  struct JBBitmapWord {
10
9
  uint256 currentWord;
11
10
  uint256 currentDepth;
@@ -12,7 +12,6 @@ import {IJB721TokenUriResolver} from "../interfaces/IJB721TokenUriResolver.sol";
12
12
  /// @custom:member contractUri The URI where this contract's metadata can be found.
13
13
  /// @custom:member tiersConfig The NFT tiers and pricing config to launch the hook with.
14
14
  /// @custom:member flags A set of boolean options to configure the hook with.
15
- // forge-lint: disable-next-line(pascal-case-struct)
16
15
  struct JBDeploy721TiersHookConfig {
17
16
  string name;
18
17
  string symbol;
@@ -10,7 +10,6 @@ import {JBPayDataHookRulesetConfig} from "./JBPayDataHookRulesetConfig.sol";
10
10
  /// @custom:member rulesetConfigurations The ruleset configurations to queue.
11
11
  /// @custom:member terminalConfigurations The terminal configurations to add for the project.
12
12
  /// @custom:member memo A memo to pass along to the emitted event.
13
- // forge-lint: disable-next-line(pascal-case-struct)
14
13
  struct JBLaunchProjectConfig {
15
14
  string projectUri;
16
15
  JBPayDataHookRulesetConfig[] rulesetConfigurations;
@@ -9,7 +9,6 @@ import {JBPayDataHookRulesetConfig} from "./JBPayDataHookRulesetConfig.sol";
9
9
  /// @custom:member rulesetConfigurations The ruleset configurations to queue.
10
10
  /// @custom:member terminalConfigurations The terminal configurations to add for the project.
11
11
  /// @custom:member memo A memo to pass along to the emitted event.
12
- // forge-lint: disable-next-line(pascal-case-struct)
13
12
  struct JBLaunchRulesetsConfig {
14
13
  uint56 projectId;
15
14
  JBPayDataHookRulesetConfig[] rulesetConfigurations;
@@ -32,7 +32,6 @@ import {JBPayDataHookRulesetMetadata} from "./JBPayDataHookRulesetMetadata.sol";
32
32
  /// its balance in each payment terminal while the ruleset is active. Amounts are fixed point numbers using the same
33
33
  /// number of decimals as the corresponding terminal. The `payoutLimit` and `surplusAllowance` parameters must fit in
34
34
  /// a `uint232`.
35
- // forge-lint: disable-next-line(pascal-case-struct)
36
35
  struct JBPayDataHookRulesetConfig {
37
36
  uint48 mustStartAtOrAfter;
38
37
  uint32 duration;
@@ -28,7 +28,6 @@ pragma solidity ^0.8.0;
28
28
  /// during
29
29
  /// this ruleset.
30
30
  /// @custom:member metadata Metadata of the metadata, up to uint8 in size.
31
- // forge-lint: disable-next-line(pascal-case-struct)
32
31
  struct JBPayDataHookRulesetMetadata {
33
32
  uint16 reservedPercent;
34
33
  uint16 cashOutTaxRate;
@@ -6,7 +6,6 @@ import {JBPayDataHookRulesetConfig} from "./JBPayDataHookRulesetConfig.sol";
6
6
  /// @custom:member projectId The ID of the project to queue rulesets for.
7
7
  /// @custom:member rulesetConfigurations The ruleset configurations to queue.
8
8
  /// @custom:member memo A memo to pass along to the emitted event.
9
- // forge-lint: disable-next-line(pascal-case-struct)
10
9
  struct JBQueueRulesetsConfig {
11
10
  uint56 projectId;
12
11
  JBPayDataHookRulesetConfig[] rulesetConfigurations;
@@ -13,7 +13,6 @@ pragma solidity ^0.8.0;
13
13
  /// purchased.
14
14
  /// @custom:member packedBools Packed boolean flags: allowOwnerMint, transfersPausable, useVotingUnits,
15
15
  /// cantBeRemoved, cantIncreaseDiscountPercent, cantBuyWithCredits.
16
- // forge-lint: disable-next-line(pascal-case-struct)
17
16
  struct JBStored721Tier {
18
17
  uint104 price;
19
18
  uint32 remainingSupply;