@bananapus/address-registry-v6 0.0.4 → 0.0.6

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.
@@ -0,0 +1,39 @@
1
+ # Administration
2
+
3
+ Admin privileges and their scope in nana-address-registry-v6.
4
+
5
+ ## Roles
6
+
7
+ None. `JBAddressRegistry` has no owner, no admin, and no access control. The contract does not inherit from `Ownable`, `AccessControl`, or any permissioned pattern.
8
+
9
+ ## Privileged Functions
10
+
11
+ ### JBAddressRegistry
12
+
13
+ | Function | Required Role | Permission ID | Scope | What It Does |
14
+ |----------|--------------|---------------|-------|--------------|
15
+ | `registerAddress(address deployer, uint256 nonce)` | None | N/A | Global | Computes a `create` address from deployer + nonce and stores the deployer mapping |
16
+ | `registerAddress(address deployer, bytes32 salt, bytes bytecode)` | None | N/A | Global | Computes a `create2` address from deployer + salt + bytecode and stores the deployer mapping |
17
+ | `deployerOf(address)` | None | N/A | Global | View function — returns the registered deployer for a given address |
18
+
19
+ Every function is callable by any address. There are no restricted operations.
20
+
21
+ ## Registration Model
22
+
23
+ - **Fully permissionless.** Any address can register any deployer/nonce or deployer/salt/bytecode combination.
24
+ - **No caller verification.** The registry does not check whether `msg.sender` is the deployer. It only verifies that the computed address is valid by storing the mapping.
25
+ - **Overwritable.** A second registration for the same computed address overwrites the previous deployer mapping. Last writer wins.
26
+ - **Permanent storage, no removal.** There is no `unregister` or `removeAddress` function. Entries can be overwritten but never deleted.
27
+ - **No approval or queue.** Registrations take effect immediately in the same transaction.
28
+
29
+ ## Admin Boundaries
30
+
31
+ There are no admins. Specifically:
32
+
33
+ - **No pause mechanism.** The registry cannot be paused or frozen.
34
+ - **No upgrade path.** The contract is not proxied or upgradeable.
35
+ - **No fee extraction.** The contract holds no funds and collects no fees.
36
+ - **No blocklist.** No address can be prevented from registering.
37
+ - **No migration.** There is no way to transfer state to a new registry contract.
38
+
39
+ The only trust assumption is on the frontend side: clients must maintain their own list of trusted deployers and use `deployerOf()` to check whether a contract was deployed by one of them. The registry itself makes no trust judgments.
@@ -0,0 +1,45 @@
1
+ # nana-address-registry-v6 — Architecture
2
+
3
+ ## Purpose
4
+
5
+ Deployer verification registry for Juicebox V6. Allows contracts deployed via `create` or `create2` to publicly register their deployer's address. Frontend clients use this to verify that hooks and other contracts were deployed by trusted deployers.
6
+
7
+ ## Contract Map
8
+
9
+ ```
10
+ src/
11
+ ├── JBAddressRegistry.sol — Registry: registerAddress (create/create2), deployerOf mapping
12
+ └── interfaces/
13
+ └── IJBAddressRegistry.sol — Interface
14
+ ```
15
+
16
+ ## Key Operations
17
+
18
+ ### Registration (create)
19
+ ```
20
+ Deployer → JBAddressRegistry.registerAddress(deployer, nonce)
21
+ → Compute address via RLP encoding of [deployer, nonce]
22
+ → Store deployerOf[computedAddress] = deployer
23
+ → Emit AddressRegistered
24
+ ```
25
+
26
+ ### Registration (create2)
27
+ ```
28
+ Deployer → JBAddressRegistry.registerAddress(deployer, salt, bytecode)
29
+ → Compute address via keccak256(0xff ++ deployer ++ salt ++ keccak256(bytecode))
30
+ → Store deployerOf[computedAddress] = deployer
31
+ → Emit AddressRegistered
32
+ ```
33
+
34
+ ### Verification
35
+ ```
36
+ Frontend → JBAddressRegistry.deployerOf(hookAddress)
37
+ → Returns deployer address (or address(0) if unregistered)
38
+ → Frontend checks deployer against trusted deployer list
39
+ ```
40
+
41
+ ## Dependencies
42
+
43
+ - `@sphinx-labs/plugins` — Deployment tooling (devDependency only)
44
+
45
+ No runtime Solidity dependencies — this is a standalone contract.
package/RISKS.md ADDED
@@ -0,0 +1,20 @@
1
+ # nana-address-registry-v6 — Risks
2
+
3
+ ## Trust Assumptions
4
+
5
+ 1. **Self-Registration** — Anyone can register any address. The registry does NOT verify that the caller actually deployed the contract. It only verifies that the computed address matches the provided parameters.
6
+ 2. **Address Computation** — Relies on correct RLP encoding (create) and keccak256 (create2) for address derivation. Standard Ethereum address computation.
7
+ 3. **Frontend Trust** — Frontends must maintain their own list of trusted deployers. The registry only provides the mapping, not a trust judgment.
8
+
9
+ ## Known Risks
10
+
11
+ | Risk | Description | Mitigation |
12
+ |------|-------------|------------|
13
+ | False registration | Anyone can call registerAddress — the computed address must match, but the "deployer" parameter is not verified as the actual deployer | Address computation ensures the deployer/nonce pair produced the address |
14
+ | Overwrite | A second registration for the same address overwrites the first | By design; last writer wins |
15
+ | No unregister | Once registered, a deployer mapping cannot be removed | Intentional; provides permanent provenance |
16
+ | Nonce range | Supports nonces up to uint64 max | Covers any realistic Ethereum nonce |
17
+
18
+ ## Privileged Roles
19
+
20
+ None — the contract is fully permissionless. Anyone can register, anyone can query.
package/STYLE_GUIDE.md ADDED
@@ -0,0 +1,468 @@
1
+ # Style Guide
2
+
3
+ How we write Solidity and organize repos across the Juicebox V6 ecosystem. `nana-core-v6` is the gold standard — when in doubt, match what it does.
4
+
5
+ ## File Organization
6
+
7
+ ```
8
+ src/
9
+ ├── Contract.sol # Main contracts in root
10
+ ├── abstract/ # Base contracts (JBPermissioned, JBControlled)
11
+ ├── enums/ # One enum per file
12
+ ├── interfaces/ # One interface per file, prefixed with I
13
+ ├── libraries/ # Pure/view logic, prefixed with JB
14
+ ├── periphery/ # Utility contracts (deadlines, price feeds)
15
+ └── structs/ # One struct per file, prefixed with JB
16
+ ```
17
+
18
+ One contract/interface/struct/enum per file. Name the file after the type it contains.
19
+
20
+ **Structs, enums, libraries, and interfaces always go in their subdirectories** (`src/structs/`, `src/enums/`, `src/libraries/`, `src/interfaces/`) — never inline in contract files or placed in `src/` root. This keeps type definitions discoverable and import paths consistent across repos.
21
+
22
+ ## Pragma Versions
23
+
24
+ ```solidity
25
+ // Contracts — pin to exact version
26
+ pragma solidity 0.8.26;
27
+
28
+ // Interfaces, structs, enums — caret for forward compatibility
29
+ pragma solidity ^0.8.0;
30
+
31
+ // Libraries — caret, may use newer features
32
+ pragma solidity ^0.8.17;
33
+ ```
34
+
35
+ ## Imports
36
+
37
+ Named imports only. Grouped by source, alphabetized within each group:
38
+
39
+ ```solidity
40
+ // External packages (alphabetized)
41
+ import {ERC2771Context} from "@openzeppelin/contracts/metatx/ERC2771Context.sol";
42
+ import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
43
+ import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
44
+ import {mulDiv} from "@prb/math/src/Common.sol";
45
+
46
+ // Local: abstract contracts
47
+ import {JBPermissioned} from "./abstract/JBPermissioned.sol";
48
+
49
+ // Local: interfaces (alphabetized)
50
+ import {IJBController} from "./interfaces/IJBController.sol";
51
+ import {IJBDirectory} from "./interfaces/IJBDirectory.sol";
52
+ import {IJBMultiTerminal} from "./interfaces/IJBMultiTerminal.sol";
53
+
54
+ // Local: libraries (alphabetized)
55
+ import {JBConstants} from "./libraries/JBConstants.sol";
56
+ import {JBFees} from "./libraries/JBFees.sol";
57
+
58
+ // Local: structs (alphabetized)
59
+ import {JBAccountingContext} from "./structs/JBAccountingContext.sol";
60
+ import {JBSplit} from "./structs/JBSplit.sol";
61
+ ```
62
+
63
+ ## Contract Structure
64
+
65
+ Section banners divide the contract into a fixed ordering. Every contract with 50+ lines uses these banners:
66
+
67
+ ```solidity
68
+ /// @notice One-line description.
69
+ contract JBExample is JBPermissioned, IJBExample {
70
+ // A library that does X.
71
+ using SomeLib for SomeType;
72
+
73
+ //*********************************************************************//
74
+ // --------------------------- custom errors ------------------------- //
75
+ //*********************************************************************//
76
+
77
+ error JBExample_SomethingFailed(uint256 amount);
78
+
79
+ //*********************************************************************//
80
+ // ------------------------- public constants ------------------------ //
81
+ //*********************************************************************//
82
+
83
+ uint256 public constant override FEE = 25;
84
+
85
+ //*********************************************************************//
86
+ // ----------------------- internal constants ------------------------ //
87
+ //*********************************************************************//
88
+
89
+ uint256 internal constant _FEE_BENEFICIARY_PROJECT_ID = 1;
90
+
91
+ //*********************************************************************//
92
+ // --------------- public immutable stored properties ---------------- //
93
+ //*********************************************************************//
94
+
95
+ IJBDirectory public immutable override DIRECTORY;
96
+
97
+ //*********************************************************************//
98
+ // --------------------- public stored properties -------------------- //
99
+ //*********************************************************************//
100
+
101
+ //*********************************************************************//
102
+ // -------------------- internal stored properties ------------------- //
103
+ //*********************************************************************//
104
+
105
+ //*********************************************************************//
106
+ // -------------------------- constructor ---------------------------- //
107
+ //*********************************************************************//
108
+
109
+ //*********************************************************************//
110
+ // ---------------------- receive / fallback ------------------------- //
111
+ //*********************************************************************//
112
+
113
+ //*********************************************************************//
114
+ // --------------------------- modifiers ----------------------------- //
115
+ //*********************************************************************//
116
+
117
+ //*********************************************************************//
118
+ // ---------------------- external transactions ---------------------- //
119
+ //*********************************************************************//
120
+
121
+ //*********************************************************************//
122
+ // ----------------------- external views ---------------------------- //
123
+ //*********************************************************************//
124
+
125
+ //*********************************************************************//
126
+ // ----------------------- public transactions ----------------------- //
127
+ //*********************************************************************//
128
+
129
+ //*********************************************************************//
130
+ // ----------------------- internal helpers -------------------------- //
131
+ //*********************************************************************//
132
+
133
+ //*********************************************************************//
134
+ // ----------------------- internal views ---------------------------- //
135
+ //*********************************************************************//
136
+
137
+ //*********************************************************************//
138
+ // ----------------------- private helpers --------------------------- //
139
+ //*********************************************************************//
140
+ }
141
+ ```
142
+
143
+ **Section order:**
144
+ 1. `using` declarations
145
+ 2. Custom errors
146
+ 3. Public constants
147
+ 4. Internal constants
148
+ 5. Public immutable stored properties
149
+ 6. Internal immutable stored properties
150
+ 7. Public stored properties
151
+ 8. Internal stored properties
152
+ 9. Constructor
153
+ 10. `receive` / `fallback`
154
+ 11. Modifiers
155
+ 12. External transactions
156
+ 13. External views
157
+ 14. Public transactions
158
+ 15. Internal helpers
159
+ 16. Internal views
160
+ 17. Private helpers
161
+
162
+ Functions are alphabetized within each section.
163
+
164
+ **Events:** Events are declared in interfaces only, never in implementation contracts. Implementations inherit events from their interface and emit them unqualified. This keeps the ABI definition in one place and allows tests to use interface-qualified event expectations (e.g., `emit IJBController.LaunchProject(...)`).
165
+
166
+ ## Interface Structure
167
+
168
+ ```solidity
169
+ /// @notice One-line description.
170
+ interface IJBExample is IJBBase {
171
+ // Events (with full NatSpec)
172
+
173
+ /// @notice Emitted when X happens.
174
+ /// @param projectId The ID of the project.
175
+ /// @param amount The amount transferred.
176
+ event SomethingHappened(uint256 indexed projectId, uint256 amount);
177
+
178
+ // Views (alphabetized)
179
+
180
+ /// @notice The directory of terminals and controllers.
181
+ function DIRECTORY() external view returns (IJBDirectory);
182
+
183
+ // State-changing functions (alphabetized)
184
+
185
+ /// @notice Does the thing.
186
+ /// @param projectId The ID of the project.
187
+ /// @return result The result.
188
+ function doThing(uint256 projectId) external returns (uint256 result);
189
+ }
190
+ ```
191
+
192
+ **Rules:**
193
+ - Events first, then views, then state-changing functions
194
+ - No custom errors in interfaces — errors belong in the implementing contract
195
+ - Full NatSpec on every event, function, and parameter
196
+ - Alphabetized within each group
197
+
198
+ ## Naming
199
+
200
+ | Thing | Convention | Example |
201
+ |-------|-----------|---------|
202
+ | Contract | PascalCase | `JBMultiTerminal` |
203
+ | Interface | `I` + PascalCase | `IJBMultiTerminal` |
204
+ | Library | PascalCase | `JBCashOuts` |
205
+ | Struct | PascalCase | `JBRulesetConfig` |
206
+ | Enum | PascalCase | `JBApprovalStatus` |
207
+ | Enum value | PascalCase | `ApprovalExpected` |
208
+ | Error | `ContractName_ErrorName` | `JBMultiTerminal_FeeTerminalNotFound` |
209
+ | Public constant | `ALL_CAPS` | `FEE`, `MAX_FEE` |
210
+ | Internal constant | `_ALL_CAPS` | `_FEE_HOLDING_SECONDS` |
211
+ | Public immutable | `ALL_CAPS` | `DIRECTORY`, `PERMISSIONS` |
212
+ | Public/external function | `camelCase` | `cashOutTokensOf` |
213
+ | Internal/private function | `_camelCase` | `_processFee` |
214
+ | Internal storage | `_camelCase` | `_accountingContextForTokenOf` |
215
+ | Function parameter | `camelCase` | `projectId`, `cashOutCount` |
216
+
217
+ ## NatSpec
218
+
219
+ **Contracts:**
220
+ ```solidity
221
+ /// @notice One-line description of what the contract does.
222
+ contract JBExample is IJBExample {
223
+ ```
224
+
225
+ **Functions:**
226
+ ```solidity
227
+ /// @notice Records funds being added to a project's balance.
228
+ /// @param projectId The ID of the project which funds are being added to.
229
+ /// @param token The token being added.
230
+ /// @param amount The amount added, as a fixed point number with the same decimals as the terminal.
231
+ /// @return surplus The new surplus after adding.
232
+ function recordAddedBalanceFor(
233
+ uint256 projectId,
234
+ address token,
235
+ uint256 amount
236
+ ) external override returns (uint256 surplus) {
237
+ ```
238
+
239
+ **Structs:**
240
+ ```solidity
241
+ /// @custom:member duration The number of seconds the ruleset lasts for. 0 means it never expires.
242
+ /// @custom:member weight How many tokens to mint per unit paid (18 decimals).
243
+ /// @custom:member weightCutPercent How much weight decays each cycle (9 decimals).
244
+ struct JBRulesetConfig {
245
+ uint32 duration;
246
+ uint112 weight;
247
+ uint32 weightCutPercent;
248
+ }
249
+ ```
250
+
251
+ **Mappings:**
252
+ ```solidity
253
+ /// @notice Context describing how a token is accounted for by a project.
254
+ /// @custom:param projectId The ID of the project.
255
+ /// @custom:param token The address of the token.
256
+ mapping(uint256 projectId => mapping(address token => JBAccountingContext)) internal _accountingContextForTokenOf;
257
+ ```
258
+
259
+ ## Numbers
260
+
261
+ Use underscores for thousands separators:
262
+
263
+ ```solidity
264
+ uint256 internal constant _FEE_HOLDING_SECONDS = 2_419_200; // 28 days
265
+ uint32 public constant MAX_WEIGHT_CUT_PERCENT = 1_000_000_000;
266
+ uint256 public constant MAX_RESERVED_PERCENT = 10_000;
267
+ ```
268
+
269
+ ## Function Calls
270
+
271
+ Use named parameters for readability when calling functions with 3+ arguments:
272
+
273
+ ```solidity
274
+ PERMISSIONS.hasPermission({
275
+ operator: sender,
276
+ account: account,
277
+ projectId: projectId,
278
+ permissionId: permissionId,
279
+ includeRoot: true,
280
+ includeWildcardProjectId: true
281
+ });
282
+ ```
283
+
284
+ ## Multiline Signatures
285
+
286
+ ```solidity
287
+ function recordCashOutFor(
288
+ address holder,
289
+ uint256 projectId,
290
+ uint256 cashOutCount,
291
+ JBAccountingContext calldata accountingContext
292
+ )
293
+ external
294
+ override
295
+ returns (
296
+ JBRuleset memory ruleset,
297
+ uint256 reclaimAmount,
298
+ JBCashOutHookSpecification[] memory hookSpecifications
299
+ )
300
+ {
301
+ ```
302
+
303
+ Modifiers and return types go on their own indented lines.
304
+
305
+ ## Error Handling
306
+
307
+ - Validate inputs with explicit `revert` + custom error
308
+ - Use `try-catch` only for external calls to untrusted contracts (hooks, fee processing)
309
+ - Always include relevant context in error parameters
310
+
311
+ ```solidity
312
+ // Direct validation
313
+ if (amount > limit) revert JBTerminalStore_InadequateControllerPayoutLimit(amount, limit);
314
+
315
+ // External call to untrusted hook
316
+ try hook.afterPayRecordedWith(context) {} catch (bytes memory reason) {
317
+ emit HookAfterPayReverted(hook, context, reason, _msgSender());
318
+ }
319
+ ```
320
+
321
+ ---
322
+
323
+ ## DevOps
324
+
325
+ ### foundry.toml
326
+
327
+ Standard config across all repos:
328
+
329
+ ```toml
330
+ [profile.default]
331
+ solc = '0.8.26'
332
+ evm_version = 'cancun'
333
+ optimizer_runs = 200
334
+ libs = ["node_modules", "lib"]
335
+ fs_permissions = [{ access = "read-write", path = "./"}]
336
+
337
+ [profile.ci_sizes]
338
+ optimizer_runs = 200
339
+
340
+ [fuzz]
341
+ runs = 4096
342
+
343
+ [invariant]
344
+ runs = 1024
345
+ depth = 100
346
+ fail_on_revert = false
347
+
348
+ [fmt]
349
+ number_underscore = "thousands"
350
+ multiline_func_header = "all"
351
+ wrap_comments = true
352
+ ```
353
+
354
+ **Variations:**
355
+ - `evm_version = 'cancun'` for repos using transient storage (buyback-hook, router-terminal, univ4-router)
356
+ - `via_ir = true` for repos hitting stack-too-deep (buyback-hook, banny-retail, univ4-lp-split-hook, deploy-all)
357
+ - `optimizer = false` only for deploy-all-v6 (stack-too-deep with optimization)
358
+
359
+ ### CI Workflows
360
+
361
+ Every repo has at minimum `test.yml` and `lint.yml`:
362
+
363
+ **test.yml:**
364
+ ```yaml
365
+ name: test
366
+ on:
367
+ pull_request:
368
+ branches: [main]
369
+ push:
370
+ branches: [main]
371
+ jobs:
372
+ forge-test:
373
+ runs-on: ubuntu-latest
374
+ steps:
375
+ - uses: actions/checkout@v4
376
+ with:
377
+ submodules: recursive
378
+ - uses: actions/setup-node@v4
379
+ with:
380
+ node-version: 22.4.x
381
+ - name: Install npm dependencies
382
+ run: npm install --omit=dev
383
+ - name: Install Foundry
384
+ uses: foundry-rs/foundry-toolchain@v1
385
+ - name: Run tests
386
+ run: forge test --fail-fast --summary --detailed --skip "*/script/**"
387
+ - name: Check contract sizes
388
+ run: FOUNDRY_PROFILE=ci_sizes forge build --sizes --skip "*/test/**" --skip "*/script/**" --skip SphinxUtils
389
+ ```
390
+
391
+ **lint.yml:**
392
+ ```yaml
393
+ name: lint
394
+ on:
395
+ pull_request:
396
+ branches: [main]
397
+ push:
398
+ branches: [main]
399
+ jobs:
400
+ forge-fmt:
401
+ runs-on: ubuntu-latest
402
+ steps:
403
+ - uses: actions/checkout@v4
404
+ - name: Install Foundry
405
+ uses: foundry-rs/foundry-toolchain@v1
406
+ - name: Check formatting
407
+ run: forge fmt --check
408
+ ```
409
+
410
+ ### package.json
411
+
412
+ ```json
413
+ {
414
+ "name": "@bananapus/address-registry-v6",
415
+ "version": "x.x.x",
416
+ "license": "MIT",
417
+ "repository": { "type": "git", "url": "git+https://github.com/Org/repo.git" },
418
+ "engines": { "node": ">=20.0.0" },
419
+ "scripts": {
420
+ "test": "forge test",
421
+ "coverage": "forge coverage --match-path \"./src/*.sol\" --report lcov --report summary"
422
+ },
423
+ "dependencies": { ... },
424
+ "devDependencies": {
425
+ "@sphinx-labs/plugins": "^0.33.2"
426
+ }
427
+ }
428
+ ```
429
+
430
+ **Scoping:** `@bananapus/` for Bananapus repos, `@rev-net/` for revnet, `@croptop/` for croptop, `@bannynet/` for banny, `@ballkidz/` for defifa.
431
+
432
+ ### remappings.txt
433
+
434
+ Every repo has a `remappings.txt`. Minimal content:
435
+
436
+ ```
437
+ @sphinx-labs/contracts/=lib/sphinx/packages/contracts/contracts/foundry
438
+ ```
439
+
440
+ Additional mappings as needed for repo-specific dependencies.
441
+
442
+ ### Formatting
443
+
444
+ Run `forge fmt` before committing. The `[fmt]` config in `foundry.toml` enforces:
445
+ - Thousands separators on numbers (`1_000_000`)
446
+ - Multiline function headers when multiple parameters
447
+ - Wrapped comments at reasonable width
448
+
449
+ CI checks formatting via `forge fmt --check`.
450
+
451
+ ### Branching
452
+
453
+ - `main` is the primary branch
454
+ - Feature branches for PRs
455
+ - All PRs trigger test + lint workflows
456
+ - Submodule checkout with `--recursive` in CI
457
+
458
+ ### Dependencies
459
+
460
+ - Solidity dependencies via npm (`node_modules/`)
461
+ - `forge-std` as a git submodule in `lib/`
462
+ - Sphinx plugins as a devDependency
463
+ - Cross-repo references use `file:../sibling-repo` in local development
464
+ - Published versions use semver ranges (`^0.0.x`) for npm
465
+
466
+ ### Contract Size Checks
467
+
468
+ CI runs `FOUNDRY_PROFILE=ci_sizes forge build --sizes` to catch contracts approaching the 24KB limit. The `ci_sizes` profile uses `optimizer_runs = 200` for realistic size measurement even when the default profile has different optimizer settings.
package/foundry.toml CHANGED
@@ -1,7 +1,7 @@
1
1
  [profile.default]
2
2
  solc = '0.8.26'
3
- evm_version = 'paris'
4
- optimizer_runs = 10000000
3
+ evm_version = 'cancun'
4
+ optimizer_runs = 200
5
5
  libs = ["node_modules", "lib"]
6
6
  fs_permissions = [{ access = "read-write", path = "./"}]
7
7
 
@@ -16,9 +16,6 @@ runs = 1024
16
16
  depth = 100
17
17
  fail_on_revert = false
18
18
 
19
- [rpc_endpoints]
20
- ethereum = "${RPC_ETHEREUM_MAINNET}"
21
-
22
19
  [fmt]
23
20
  number_underscore = "thousands"
24
21
  multiline_func_header = "all"
package/package.json CHANGED
@@ -1,11 +1,14 @@
1
1
  {
2
2
  "name": "@bananapus/address-registry-v6",
3
- "version": "0.0.4",
3
+ "version": "0.0.6",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "git+https://github.com/Bananapus/nana-address-registry-v6"
8
8
  },
9
+ "engines": {
10
+ "node": ">=20.0.0"
11
+ },
9
12
  "scripts": {
10
13
  "test": "forge test",
11
14
  "test:fork": "FOUNDRY_PROFILE=CI forge test",
@@ -15,6 +18,6 @@
15
18
  "artifacts": "source ./.env && npx sphinx artifacts --org-id 'ea165b21-7cdc-4d7b-be59-ecdd4c26bee4' --project-name 'nana-address-registry-v5'"
16
19
  },
17
20
  "dependencies": {
18
- "@sphinx-labs/plugins": "^0.33.1"
21
+ "@sphinx-labs/plugins": "^0.33.2"
19
22
  }
20
23
  }
@@ -13,7 +13,7 @@ import {IJBAddressRegistry} from "./interfaces/IJBAddressRegistry.sol";
13
13
  /// nonce (for `create`) or `create2` salt and deployment bytecode (for `create2`).
14
14
  contract JBAddressRegistry is IJBAddressRegistry {
15
15
  //*********************************************************************//
16
- // -------------------------------- errors --------------------------- //
16
+ // --------------------------- custom errors ------------------------- //
17
17
  //*********************************************************************//
18
18
 
19
19
  /// @notice Thrown when a nonce exceeds the maximum value supported by the RLP encoding (uint64 max).
@@ -62,7 +62,7 @@ contract JBAddressRegistry is IJBAddressRegistry {
62
62
  }
63
63
 
64
64
  //*********************************************************************//
65
- // ---------------------- internal transactions ---------------------- //
65
+ // -------------------------- internal views ------------------------- //
66
66
  //*********************************************************************//
67
67
 
68
68
  /// @notice Compute the address of a contract deployed using `create` based on the deployer's address and nonce.
@@ -102,6 +102,10 @@ contract JBAddressRegistry is IJBAddressRegistry {
102
102
  }
103
103
  }
104
104
 
105
+ //*********************************************************************//
106
+ // ------------------------ internal functions ----------------------- //
107
+ //*********************************************************************//
108
+
105
109
  /// @notice Register a contract's deployer in the `deployerOf` mapping.
106
110
  /// @param addr The deployed contract's address.
107
111
  /// @param deployer The deployer's address.
@@ -1,7 +1,12 @@
1
1
  // SPDX-License-Identifier: MIT
2
2
  pragma solidity ^0.8.0;
3
3
 
4
+ /// @notice A registry that maps deployed contract addresses to their deployers.
4
5
  interface IJBAddressRegistry {
6
+ /// @notice Emitted when a contract address is registered.
7
+ /// @param addr The address of the registered contract.
8
+ /// @param deployer The address of the contract's deployer.
9
+ /// @param caller The address that called the register function.
5
10
  event AddressRegistered(address indexed addr, address indexed deployer, address caller);
6
11
 
7
12
  /// @notice Returns the deployer of a given contract which has been registered.
@@ -276,7 +276,7 @@ contract JBAddressRegistryEdge is Test {
276
276
  }
277
277
 
278
278
  // =========================================================================
279
- // Nonce > uint64 - reverts with NonceTooLarge (L-67 fix extended to uint64)
279
+ // Nonce > uint64 - reverts with NonceTooLarge (extended to uint64)
280
280
  // =========================================================================
281
281
 
282
282
  /// @notice Nonces above uint64 max revert instead of silently truncating.
@@ -290,7 +290,7 @@ contract JBAddressRegistryEdge is Test {
290
290
  registry.registerAddress(deployer1, tooLargeNonce);
291
291
  }
292
292
 
293
- /// @notice Nonces in the uint32-uint64 range now succeed (L-67 fix extended support).
293
+ /// @notice Nonces in the uint32-uint64 range now succeed (extended support).
294
294
  function test_nonceInUint40Range_succeeds() public {
295
295
  registry.registerAddress(deployer, uint256(type(uint40).max));
296
296
  }
@@ -5,7 +5,7 @@ import {Test} from "forge-std/Test.sol";
5
5
  import {JBAddressRegistry} from "../../src/JBAddressRegistry.sol";
6
6
 
7
7
  /// @title L67_NonceTruncation
8
- /// @notice Regression test for L-67: _addressFrom originally only handled nonces up to uint32 max,
8
+ /// @notice _addressFrom originally only handled nonces up to uint32 max,
9
9
  /// silently truncating larger values. The fix extends RLP encoding to uint64 max and adds
10
10
  /// an explicit revert for nonces beyond that range.
11
11
  contract L67_NonceTruncation is Test {
@@ -21,7 +21,7 @@ contract L67_NonceTruncation is Test {
21
21
  registry.registerAddress(deployer, type(uint32).max);
22
22
  }
23
23
 
24
- /// @notice Nonce one above uint32 max should now succeed (uint64 support added in L-67 fix).
24
+ /// @notice Nonce one above uint32 max should now succeed (uint64 support added).
25
25
  function test_nonceAboveUint32Max_succeeds() public {
26
26
  uint256 nonce = uint256(type(uint32).max) + 1;
27
27
  // Should not revert -- the fix extended support to uint64.