@bananapus/core-v6 0.0.34 → 0.0.35

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/ARCHITECTURE.md CHANGED
@@ -2,49 +2,73 @@
2
2
 
3
3
  ## Purpose
4
4
 
5
- `nana-core-v6` is the protocol root. It owns project identity, permissions, rulesets, token supply, treasury balances, payout limits, fee logic, and the hook interfaces that every extension repo composes with.
5
+ `nana-core-v6` is the protocol root for the V6 stack. It owns project identity, rulesets, permissions, treasury balances, token issuance, fee behavior, payout limits, and the hook interfaces every extension repo composes with.
6
6
 
7
- If a change affects accounting, supply, fee behavior, terminal routing, or permission semantics, this is the repo that defines the source of truth.
7
+ If a change affects accounting, supply, fee logic, terminal routing, or permission semantics, this repo is the source of truth.
8
8
 
9
- ## Boundaries
9
+ ## System Overview
10
10
 
11
- - The core owns balance and supply transitions.
12
- - Extensions may adjust economics through hooks, but they should not invent competing ledgers.
13
- - The core deliberately avoids app-specific behaviors like NFT composition, DEX routing strategy, or bridge-specific message transport.
11
+ `JBController`, `JBMultiTerminal`, and `JBTerminalStore` form the main execution and accounting pipeline. `JBDirectory`, `JBRulesets`, `JBProjects`, `JBTokens`, `JBPermissions`, `JBSplits`, and related contracts provide the routing, identity, and shared state that all downstream repos depend on. `JBTerminalStore` is terminal-scoped through `msg.sender`, so each terminal records its own balances and usage against the shared ruleset and price surfaces. Extensions may influence economics through hook interfaces, but they should not create competing ledgers.
14
12
 
15
- ## Main Components
13
+ ## Core Invariants
16
14
 
17
- | Component | Responsibility |
18
- | --- | --- |
19
- | `JBMultiTerminal` | Entry point for payments, cash outs, payouts, balance additions, and fee handling |
20
- | `JBTerminalStore` | Bookkeeping and preview math for payment, payout, allowance, and cash-out paths |
21
- | `JBController` | Project launch, ruleset queueing, token minting and burning, split-group updates |
22
- | `JBDirectory` | Maps projects to controllers and terminals |
23
- | `JBRulesets` | Time-ordered ruleset lifecycle and approval-hook integration |
24
- | `JBTokens`, `JBERC20`, `JBProjects` | Token and project identity surfaces |
25
- | `JBSplits`, `JBFundAccessLimits`, `JBPrices`, `JBPermissions` | Shared state for distribution, limits, price conversion, and authorization |
15
+ - Preview functions must remain behaviorally aligned with state-changing functions.
16
+ - Data hooks run before settlement and may alter economics; pay and cash-out hooks run after settlement.
17
+ - Reserved tokens and other pending supply affect supply-sensitive math before distribution.
18
+ - Terminal balances, fee accounting, reclaim math, and surplus calculations must agree.
19
+ - Fee logic taxes fund egress, not every internal rebalance. Same-terminal project routing is a special case and must stay coherent with fee-free surplus tracking.
20
+ - Rulesets are time-ordered and approval-aware, and many deployer repos depend on predictable ID progression.
21
+ - Permission checks are protocol validity checks, not UI affordances.
22
+
23
+ ## Modules
24
+
25
+ | Module | Responsibility | Notes |
26
+ | --- | --- | --- |
27
+ | `JBMultiTerminal` | Payment, cash-out, payout, allowance, and fee entrypoint | Execution surface |
28
+ | `JBTerminalStore` | Shared accounting and preview math | Economic source of truth |
29
+ | `JBController` | Launch, queue rulesets, mint, burn, and split-group updates | Supply and configuration |
30
+ | `JBDirectory`, `JBRulesets` | Project routing and time-based ruleset lifecycle | Coordination layer |
31
+ | `JBProjects`, `JBTokens`, `JBERC20` | Identity and token surfaces | Ownership and tokenization |
32
+ | `JBPermissions`, `JBSplits`, `JBFundAccessLimits`, `JBPrices` | Shared authorization and configuration state | Cross-repo dependencies |
26
33
 
27
- ## Runtime Model
34
+ ## Trust Boundaries
35
+
36
+ - This repo owns canonical balance and supply transitions.
37
+ - Hook repos may adjust inputs and post-settlement side effects, but they should not replace the ledger defined here.
38
+ - External price feeds, Permit2, and ERC-20 behavior are dependencies, but accounting truth stays in core.
39
+
40
+ ## Critical Flows
28
41
 
29
42
  ### Payment
30
43
 
31
44
  ```text
32
45
  terminal receives funds
33
- -> terminal store reads the current ruleset and optional data hooks
34
- -> store computes weight-based minting results
46
+ -> terminal store reads the active ruleset and optional data hooks
47
+ -> before-pay data hook can modify weight and return pay-hook specs
48
+ -> terminal store records payment against the terminal-scoped ledger
35
49
  -> controller mints beneficiary tokens and accrues reserved tokens
36
- -> pay hooks execute only after settlement
50
+ -> pay hooks run only after settlement
37
51
  ```
38
52
 
39
53
  ### Cash Out
40
54
 
41
55
  ```text
42
56
  holder requests redemption
43
- -> terminal store computes reclaim amount from surplus, supply, and tax settings
44
- -> optional data hooks can adjust the calculation inputs
57
+ -> terminal store reads current ruleset, balances, and supply inputs
58
+ -> before-cash-out data hook can modify reclaim inputs and hook specs
59
+ -> terminal store records the cash out against the terminal-scoped ledger
45
60
  -> controller burns tokens
46
- -> terminal pays the reclaim amount and routes protocol fees
47
- -> cash-out hooks execute only after settlement
61
+ -> terminal pays reclaim value and routes protocol fees
62
+ -> cash-out hooks run only after settlement
63
+ ```
64
+
65
+ ### Launch And Queue Rulesets
66
+
67
+ ```text
68
+ owner, operator, or omnichain ruleset operator
69
+ -> controller launches or queues rulesets
70
+ -> launch path also sets the controller in the directory and configures terminals
71
+ -> rulesets become the source of truth for subsequent pay, cash-out, and admin constraints
48
72
  ```
49
73
 
50
74
  ### Payouts And Allowances
@@ -53,32 +77,50 @@ holder requests redemption
53
77
  authorized caller
54
78
  -> consumes payout limits or surplus allowances
55
79
  -> funds move to splits, projects, hooks, or direct recipients
80
+ -> same-terminal project payouts stay inside terminal accounting, may accrue fee-free surplus, and must not accidentally mint against the payer's own balance
56
81
  ```
57
82
 
58
- ## Critical Invariants
59
-
60
- - Preview functions must remain behaviorally aligned with state-changing functions.
61
- - Data hooks run before settlement and may alter the economics; pay and cash-out hooks run after settlement. That phase boundary is intentional.
62
- - Reserved tokens and pending reserves affect supply-sensitive math even before distribution.
63
- - Terminal balances, fee accounting, and surplus calculations must agree. Any drift here contaminates every product repo.
64
- - Rulesets are time-ordered and approval-aware; deployment wrappers depend on predictable ID progression and activation semantics.
65
- - Permission checks are not a UI concern. They are part of protocol state transition validity.
83
+ ## Accounting Model
66
84
 
67
- ## Where Complexity Lives
85
+ This repo owns the canonical ledger for balances, fees, supply-sensitive reclaim math, payout limits, allowances, reserved tokens, and preview calculations. Other repos may wrap or influence these values, but none should duplicate them.
68
86
 
69
- - `JBMultiTerminal`, `JBTerminalStore`, and `JBController` form one accounting pipeline and are easiest to misunderstand when read separately.
70
- - Preview paths deliberately mirror state-changing paths; keeping them aligned is a permanent maintenance burden.
71
- - Fee-free surplus, held fees, and payout/allowance interactions create edge cases that are small in code size but large in blast radius.
87
+ `JBTerminalStore` keeps terminal balances, payout-limit usage, and surplus-allowance usage. That state is terminal-scoped, but not all reset boundaries are the same: payout-limit usage is tracked by ruleset cycle number, while surplus-allowance usage is tracked by `ruleset.id`. Auto-cycling a duration-based ruleset does not reset allowance usage; queueing a new ruleset does.
72
88
 
73
- ## Dependencies
89
+ ## Security Model
74
90
 
75
- - `nana-permission-ids-v6` for the shared permission namespace
76
- - OpenZeppelin, PRBMath, Chainlink, and Permit2 for standards and math utilities
91
+ - `JBMultiTerminal`, `JBTerminalStore`, and `JBController` should be reviewed as one pipeline.
92
+ - `JBTerminalStore` is shared logic but terminal-scoped state. Misunderstanding that split causes bad accounting assumptions.
93
+ - Small changes in fee or surplus logic can affect every downstream repo.
94
+ - Same-terminal project payouts, fee-free surplus capping, and migration cleanup are coupled. Changing one without the others creates fee bypasses or overcharges.
95
+ - `allowOwnerMinting` is not a universal mint kill switch. Terminals, the current data hook, and hook-authorized callers can still mint through the controller path.
96
+ - Hook ordering and preview-execution alignment are permanent maintenance obligations.
77
97
 
78
98
  ## Safe Change Guide
79
99
 
80
- - Start any nontrivial change by tracing both the preview path and the state-changing path.
81
- - Read downstream hook repos before changing hook interfaces or metadata expectations.
82
- - Keep fee logic, balance logic, and surplus logic in sync; "small" tweaks here are almost always ecosystem-wide changes.
83
- - When adding permissions or changing who is checked against a permission, update ecosystem docs and downstream assumptions immediately.
84
- - If a change seems local inside core, assume it is not until proven otherwise.
100
+ - Trace both preview and state-changing paths for any nontrivial change.
101
+ - Read downstream hook repos before changing hook metadata or interface expectations.
102
+ - Keep fee logic, balance logic, reclaim math, and surplus math synchronized.
103
+ - If you change payouts between projects on the same terminal, re-check self-pay revert behavior, fee-free surplus accumulation, and the post-pay cap against recorded balance.
104
+ - If you change ruleset rollover semantics, re-check which usage counters reset on cycle progression versus new ruleset IDs.
105
+ - If permissions change, update shared docs and downstream assumptions at the same time.
106
+
107
+ ## Canonical Checks
108
+
109
+ - fee-free surplus and same-terminal payout behavior:
110
+ `test/TestFeeFreeCashOutBypass.sol`
111
+ - migration and terminal-accounting continuity:
112
+ `test/TestTerminalMigration.sol`
113
+ - ruleset ordering and transition behavior:
114
+ `test/RulesetTransitions.t.sol`
115
+
116
+ ## Source Map
117
+
118
+ - `src/JBController.sol`
119
+ - `src/JBMultiTerminal.sol`
120
+ - `src/JBTerminalStore.sol`
121
+ - `src/JBDirectory.sol`
122
+ - `src/JBRulesets.sol`
123
+ - `src/JBPermissions.sol`
124
+ - `test/TestFeeFreeCashOutBypass.sol`
125
+ - `test/TestTerminalMigration.sol`
126
+ - `test/RulesetTransitions.t.sol`
@@ -2,7 +2,7 @@
2
2
 
3
3
  This is the core Juicebox V6 protocol. Most ecosystem invariants reduce to this repo eventually.
4
4
 
5
- ## Objective
5
+ ## Audit Objective
6
6
 
7
7
  Find issues that:
8
8
  - break terminal solvency or internal accounting
@@ -45,7 +45,7 @@ That order mirrors how most high-severity issues emerge:
45
45
  - tokens are minted or burned
46
46
  - permissions and price context decide whether the move was legitimate
47
47
 
48
- ## System Model
48
+ ## Security Model
49
49
 
50
50
  Core roles:
51
51
  - `JBMultiTerminal`: holds funds and executes pay, payout, cash-out, allowance, and fee-processing flows
@@ -67,6 +67,23 @@ Core ordering to keep in mind:
67
67
  - controller mint and burn operations happen around terminal flows, not as a separate settlement layer
68
68
  - hooks can turn what looks like a simple pay or cash-out into a multi-contract composition
69
69
 
70
+ ## Roles And Privileges
71
+
72
+ | Role | Powers | How constrained |
73
+ |------|--------|-----------------|
74
+ | Project owner and operators | Configure rulesets, limits, routing, and permissions | Must stay inside the explicit permission model |
75
+ | Terminal | Hold funds and execute settlement | Must remain solvent relative to internal accounting |
76
+ | Controller | Mint, burn, and manage project lifecycle | Must not bypass project-scoped authorization |
77
+ | Hooks and splits | Extend pay and cash-out behavior | Must not make previews and accounting irreconcilable |
78
+
79
+ ## Integration Assumptions
80
+
81
+ | Dependency | Assumption | What breaks if wrong |
82
+ |------------|------------|----------------------|
83
+ | Price feeds | Currency conversions are fresh and coherent | Cross-currency flows misprice |
84
+ | Hook ecosystem | External hooks obey documented interfaces | Settlement becomes unsafe after control transfer |
85
+ | Directory and migration surfaces | Canonical routing changes are authentic | Funds or permissions shift to the wrong place |
86
+
70
87
  ## Critical Invariants
71
88
 
72
89
  1. Terminal solvency
@@ -93,22 +110,7 @@ When fee payment is deferred, later replenishment or migration behavior must not
93
110
  8. Preview coherence
94
111
  `previewPayFor` and `previewCashOutFrom` should not become meaningfully inconsistent with execution in ways downstream repos can exploit.
95
112
 
96
- ## Threat Model
97
-
98
- Prioritize:
99
- - hook-driven reentrancy or state-ordering issues
100
- - price-feed failure and cross-currency conversions
101
- - fee-processing failure paths
102
- - migration and feeless-address edge cases
103
- - ruleset-boundary timing attacks
104
- - wildcard or root permission escalation
105
-
106
- The highest-yield attacker mindsets here are:
107
- - a malicious hook that receives control after balances move but before the full user flow is conceptually finished
108
- - a project owner exploiting migration, limits, or feeless settings rather than breaking access control directly
109
- - a cross-currency user extracting value from rounding or stale price conversions
110
-
111
- ## Hotspots
113
+ ## Attack Surfaces
112
114
 
113
115
  - `pay`, `cashOutTokensOf`, `sendPayoutsOf`, and `useAllowanceOf`
114
116
  - `preview*` paths when downstream repos treat them as execution truth
@@ -117,34 +119,19 @@ The highest-yield attacker mindsets here are:
117
119
  - controller migration and terminal migration
118
120
  - `setPermissionsFor` and any wildcard semantics
119
121
 
120
- ## Sequences Worth Replaying
121
-
122
- 1. `pay` with a data hook that returns altered weight and hook specs, then re-enter through a pay hook.
123
- 2. `cashOutTokensOf` when `useTotalSurplusForCashOuts` or cross-terminal surplus logic matters.
124
- 3. `sendPayoutsOf` into splits that route to another project, hook, or failing beneficiary.
125
- 4. held-fee accumulation -> migration or balance depletion -> `processHeldFeesOf`.
126
- 5. permission grants involving operators, wildcard project IDs, or later controller changes.
122
+ Replay these sequences:
123
+ 1. `pay` with a data hook that alters weight or hook specs and then reenters through a pay hook
124
+ 2. `cashOutTokensOf` when cross-terminal surplus and `useTotalSurplusForCashOuts` matter
125
+ 3. `sendPayoutsOf` into splits that route to another project, hook, or failing beneficiary
126
+ 4. held-fee accumulation followed by migration or balance depletion
127
+ 5. permission grants involving operators, wildcard project IDs, or later controller changes
127
128
 
128
- ## Finding Bar
129
+ ## Accepted Risks Or Behaviors
129
130
 
130
- The best findings in this repo usually prove one of these:
131
- - the store records more value than the terminal can safely honor
132
- - a limit is consumed too late, after externally controlled code can already profit
133
- - a migration or held-fee edge path changes who ultimately bears an obligation
134
- - permissions that look project-scoped become ecosystem-relevant through wildcard or routing semantics
131
+ - Hooks are intentionally powerful extension points; safety depends on clear sequencing and bounded trust, not on avoiding composition.
135
132
 
136
- ## Build And Verification
133
+ ## Verification
137
134
 
138
- Standard workflow:
139
135
  - `npm install`
140
136
  - `forge build`
141
137
  - `forge test`
142
-
143
- The current test suite already targets:
144
- - flash-loan and economic exploits
145
- - permissions invariants
146
- - ruleset transitions
147
- - fee and migration edge cases
148
- - multi-token and cross-currency surplus behavior
149
-
150
- The highest-value findings in this repo are the ones that make downstream hooks or deployers unsafe even when those repos are otherwise correct.
package/README.md CHANGED
@@ -3,7 +3,12 @@
3
3
  `@bananapus/core-v6` is the core protocol package for Juicebox on EVM chains. It defines projects, rulesets, terminals, permissions, token issuance, cash outs, splits, price feeds, and the accounting surfaces that the rest of the V6 ecosystem builds on.
4
4
 
5
5
  Docs: <https://docs.juicebox.money>
6
- Architecture: [ARCHITECTURE.md](./ARCHITECTURE.md)
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)
7
12
 
8
13
  ## Overview
9
14
 
@@ -18,7 +23,7 @@ The core package provides:
18
23
  - operator permissions through `JBPermissions`
19
24
  - on-chain price-feed routing through `JBPrices`
20
25
 
21
- Use this repo when you need the canonical protocol invariant. Do not duplicate its logic in downstream packages unless the repo is explicitly intended to wrap or extend the core surface.
26
+ Use this repo when you need the canonical protocol accounting and execution surfaces. Do not duplicate its logic in downstream packages unless the repo is explicitly intended to wrap or extend the core surface.
22
27
 
23
28
  If you only read one repo before auditing the rest of the ecosystem, read this one.
24
29
 
@@ -31,7 +36,7 @@ The core protocol is easiest to reason about in four layers:
31
36
  3. accounting: `JBTerminalStore`
32
37
  4. permissions and external context: `JBPermissions`, `JBPrices`, feeless-address and deadline helpers
33
38
 
34
- Most integrations touch only layer 2. Most economically important bugs leak through layer 3.
39
+ Many integrations touch only layer 2, while many economically important bugs are easiest to understand from layer 3.
35
40
 
36
41
  The shortest path through the repo is:
37
42
 
@@ -78,6 +83,14 @@ The shortest path through the repo is:
78
83
 
79
84
  When in doubt, read the state-owning contract before the contract that merely forwards into it.
80
85
 
86
+ ## High-Signal Tests
87
+
88
+ 1. `test/TestPayBurnRedeemFlow.sol`
89
+ 2. `test/TestTerminalPreviewParity.sol`
90
+ 3. `test/invariants/TerminalStoreInvariant.t.sol`
91
+ 4. `test/invariants/RulesetsInvariant.t.sol`
92
+ 5. `test/audit/CrossTerminalSurplusSpoof.t.sol`
93
+
81
94
  ## Install
82
95
 
83
96
  ```bash
@@ -125,3 +138,9 @@ script/
125
138
  - fee, surplus, and reclaim logic are economically sensitive and remain high-priority audit surfaces
126
139
 
127
140
  The fastest way to misunderstand V6 is to treat the core contracts like a simple crowdfunding terminal. They are closer to a configurable accounting and settlement substrate.
141
+
142
+ ## For AI Agents
143
+
144
+ - Start with `JBController`, `JBMultiTerminal`, and `JBTerminalStore`; do not summarize core behavior from helper libraries alone.
145
+ - Distinguish controller configuration from terminal execution and from store accounting.
146
+ - If a behavior involves hooks, inspect the hook repo too before treating the preview or execution path as canonical.
package/RISKS.md CHANGED
@@ -144,6 +144,7 @@ No `ReentrancyGuard` is used. The system relies on state ordering and the `Inade
144
144
  - **No state modification risk.** Preview functions cannot change balances, mint/burn tokens, or consume limits. They are safe to call from any context.
145
145
  - **Preview-execution divergence.** Preview functions and their corresponding real operations share computation logic but execute in different contexts. `previewPayFor` calls `STORE.previewPayFrom` which invokes the data hook's `beforePayRecordedWith` via `staticcall`. The real `pay` path invokes the same hook but state changes between preview and execution (other payments, cash outs, ruleset transitions) can change the data hook's response. Callers should treat preview results as estimates, not guarantees — especially for projects with stateful data hooks.
146
146
  - **Gas griefing via data hooks in previews.** Since `previewPayFor` and `previewCashOutFrom` invoke data hooks, a gas-expensive data hook can make preview calls prohibitively expensive. This affects frontends and indexers that rely on preview functions for quote display. Unlike the real operations (which have economic incentive to complete), preview calls have no built-in gas limit on the data hook invocation.
147
+ - **Not all read-only cash-out estimates are hook-aware.** `JBTerminalStore.currentReclaimableSurplusOf` and `currentTotalReclaimableSurplusOf` intentionally do not run the data hook. They use the current ruleset's plain `cashOutTaxRate` and the controller-reported total supply, so they cannot reflect hook-provided overrides such as omnichain or custom `effectiveTotalSupply` logic. Integrators should use `previewCashOutFrom` or simulate `recordCashOutFor` when they need an estimate that matches hook-adjusted execution more closely.
147
148
 
148
149
  ## 7. Integration Risks
149
150
 
@@ -174,6 +175,12 @@ No `ReentrancyGuard` is used. The system relies on state ordering and the `Inade
174
175
 
175
176
  - `JBTerminalStore.recordAddedBalanceFor` has **no access control**. Any address can call it. The balance is keyed by `msg.sender` (the terminal address), so only a terminal can inflate its own recorded balance. This is safe as long as all terminals correctly track their actual holdings. A buggy or malicious terminal implementation could call `recordAddedBalanceFor` without actually receiving tokens, inflating the recorded balance above actual holdings.
176
177
 
178
+ ### Split and Owner-Payout Failure Semantics
179
+
180
+ - **Failed split payouts still consume payout limit.** Core decrements balance and increments used payout limit before downstream split transfers are attempted. If a split payout later fails, the amount is returned to project balance, but the payout limit consumption is not rewound. This is intentional fail-open accounting: one bad split should not revert the whole payout fanout, but operators should not assume "returned to balance" also means "payout limit restored".
181
+ - **Failed owner transfers also consume payout limit.** The leftover owner payout path uses the same pattern as split payouts: if the owner transfer fails, funds return to project balance, but the payout limit remains consumed for that cycle.
182
+ - **Split hook reverts after token transfer strand tokens at the hook.** In reserved-token distributions, the controller transfers tokens to the split hook before calling `processSplitWith`. If that hook call then reverts, core emits `SplitHookReverted` but does not claw the tokens back. Integrators should treat split hooks as token-custody recipients, not pure callbacks.
183
+
177
184
  ## 8. Accepted Behaviors
178
185
 
179
186
  ### 8.1 Cross-terminal surplus is an explicit trust boundary
package/SKILLS.md CHANGED
@@ -3,19 +3,23 @@
3
3
  ## Use This File For
4
4
 
5
5
  - Use this file when the task touches protocol core behavior: payments, cash-outs, terminals, controller actions, rulesets, splits, tokens, permissions, or price feeds.
6
- - Start here if you know the issue is in core, then open the specific contract that owns the state transition you are debugging.
6
+ - Start here if you know the issue is in core, then identify the single state transition being changed before reading broadly. In this repo, most bugs reduce to controller lifecycle, terminal execution, store accounting, or ruleset state.
7
7
 
8
8
  ## Read This Next
9
9
 
10
10
  | If you need... | Open this next |
11
11
  |---|---|
12
- | Repo overview and protocol framing | [`README.md`](./README.md) |
12
+ | Repo overview and protocol framing | [`README.md`](./README.md), [`ARCHITECTURE.md`](./ARCHITECTURE.md) |
13
13
  | Controller and project lifecycle behavior | [`src/JBController.sol`](./src/JBController.sol), [`src/JBProjects.sol`](./src/JBProjects.sol), [`src/JBTokens.sol`](./src/JBTokens.sol) |
14
14
  | Payment, cash-out, surplus, and fee accounting | [`src/JBMultiTerminal.sol`](./src/JBMultiTerminal.sol), [`src/JBTerminalStore.sol`](./src/JBTerminalStore.sol), [`src/JBFundAccessLimits.sol`](./src/JBFundAccessLimits.sol) |
15
15
  | Rulesets, permissions, directory, and prices | [`src/JBRulesets.sol`](./src/JBRulesets.sol), [`src/JBPermissions.sol`](./src/JBPermissions.sol), [`src/JBDirectory.sol`](./src/JBDirectory.sol), [`src/JBPrices.sol`](./src/JBPrices.sol) |
16
16
  | Shared math, metadata parsing, and constants | [`src/libraries/`](./src/libraries/), [`src/structs/`](./src/structs/), [`src/enums/`](./src/enums/) |
17
17
  | Periphery helpers and deployment | [`src/periphery/`](./src/periphery/), [`script/Deploy.s.sol`](./script/Deploy.s.sol), [`script/DeployPeriphery.s.sol`](./script/DeployPeriphery.s.sol) |
18
- | Invariants, fork tests, and security/economic regressions | [`test/formal/`](./test/formal/), [`test/fork/`](./test/fork/), [`test/audit/`](./test/audit/), [`test/helpers/`](./test/helpers/) |
18
+ | Payment and cash-out entrypoint surface | [`references/entrypoints.md`](./references/entrypoints.md) |
19
+ | Packed metadata, gotchas, errors, and hook return shapes | [`references/types-errors-events.md`](./references/types-errors-events.md) |
20
+ | Cash-out, payment, and terminal accounting proofs | [`test/TestPayBurnRedeemFlow.sol`](./test/TestPayBurnRedeemFlow.sol), [`test/TestCashOut.sol`](./test/TestCashOut.sol), [`test/TestMultiTerminalSurplus.sol`](./test/TestMultiTerminalSurplus.sol), [`test/TestTerminalPreviewParity.sol`](./test/TestTerminalPreviewParity.sol) |
21
+ | Permissions, rulesets, and invariants | [`test/TestPermissions.sol`](./test/TestPermissions.sol), [`test/PermissionEscalation.t.sol`](./test/PermissionEscalation.t.sol), [`test/TestRulesetQueueing.sol`](./test/TestRulesetQueueing.sol), [`test/ComprehensiveInvariant.t.sol`](./test/ComprehensiveInvariant.t.sol), [`test/PermissionsInvariant.t.sol`](./test/PermissionsInvariant.t.sol) |
22
+ | Economic, exploit, and weird-token coverage | [`test/EconomicSimulation.t.sol`](./test/EconomicSimulation.t.sol), [`test/CoreExploitTests.t.sol`](./test/CoreExploitTests.t.sol), [`test/FlashLoanAttacks.t.sol`](./test/FlashLoanAttacks.t.sol), [`test/WeirdTokenTests.t.sol`](./test/WeirdTokenTests.t.sol), [`test/AuditFixes.t.sol`](./test/AuditFixes.t.sol) |
19
23
 
20
24
  ## Repo Map
21
25
 
@@ -40,5 +44,13 @@ The core Juicebox V6 protocol on EVM: a modular system for launching treasury-ba
40
44
  ## Working Rules
41
45
 
42
46
  - Open source before relying on any summary here. This skill is a router, not the ground truth.
43
- - For runtime bugs, start from the terminal/controller/store contract that owns the state transition.
47
+ - For runtime bugs, start from the terminal/controller/store contract that owns the state transition. Most user-facing behavior is computed there, not in helpers or interfaces.
48
+ - `JBMultiTerminal` and `JBTerminalStore` are a pair. If you change one without re-deriving the other’s assumptions, expect accounting drift.
49
+ - Payment and cash-out previews are not optional convenience APIs. `previewPayFrom` and `previewCashOutFrom` are part of the protocol surface and need to stay aligned with execution semantics.
50
+ - Payout limits reset by ruleset cycle number, but surplus allowances are keyed by `ruleset.id`, not cycle number. Do not assume they reset together.
51
+ - Fee handling is nuanced. Re-check held fees, fee-free surplus tracking, and feeless-address behavior before changing payout or cash-out logic.
52
+ - Fee-free surplus is a bounded anti-bypass mechanism, not a generic exemption bucket. Re-check lifecycle capping and migration/reset behavior before changing cash-out or payout flows.
44
53
  - For config or weird value-shape issues, open `references/types-errors-events.md` before changing structs or metadata packing.
54
+ - Terminal previews, accounting, and fee behavior are tightly coupled. If one changes, assume at least one of the others needs verification.
55
+ - Long-lived rulesets have a real cache boundary. If the issue involves extreme cycle counts, inspect `JBRulesets.updateRulesetWeightCache(...)` and the surrounding tests before touching weight math.
56
+ - When a bug smells cross-repo, prove it is not really coming from a hook, router, or downstream deployer before patching core.