@bananapus/address-registry-v6 0.0.16 → 0.0.17

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/ADMINISTRATION.md CHANGED
@@ -2,6 +2,32 @@
2
2
 
3
3
  Admin privileges and their scope in nana-address-registry-v6.
4
4
 
5
+ ## At A Glance
6
+
7
+ | Item | Details |
8
+ |------|---------|
9
+ | Scope | Permissionless deployer registration and lookup only. There is no privileged admin surface. |
10
+ | Operators | Anyone can register address/deployer relationships; clients decide which deployers they trust. |
11
+ | Highest-risk actions | Relying on stale cached registry data or treating registry entries as trust endorsements instead of raw claims. |
12
+ | Recovery posture | Registry entries can be overwritten but not deleted. Operational recovery is client-side: re-check entries, maintain trusted deployer lists, or migrate consumers to a new registry. |
13
+
14
+ ## Routine Operations
15
+
16
+ - Re-check `deployerOf()` at time of use instead of caching it indefinitely.
17
+ - Pair registry lookups with a separate trusted-deployer allowlist in clients or indexing infrastructure.
18
+ - Treat every registration as permissionless input, not proof that the caller was authorized by the deployer.
19
+
20
+ ## One-Way Or High-Risk Actions
21
+
22
+ - There is no pause, owner override, or deletion path.
23
+ - A later registration can overwrite an earlier mapping for the same computed address.
24
+ - The registry does not verify that code is deployed at the registered address.
25
+
26
+ ## Recovery Notes
27
+
28
+ - If client trust assumptions change, fix the client or indexer. The contract itself cannot block or roll back bad registrations.
29
+ - If the ecosystem needs different trust guarantees, the recovery path is a new registry design and client migration, not an admin action here.
30
+
5
31
  ## Roles
6
32
 
7
33
  None. `JBAddressRegistry` has no owner, no admin, and no access control. The contract does not inherit from `Ownable`, `AccessControl`, or any permissioned pattern.
package/ARCHITECTURE.md CHANGED
@@ -1,57 +1,48 @@
1
- # nana-address-registry-v6 — Architecture
1
+ # Architecture
2
2
 
3
3
  ## Purpose
4
4
 
5
- Juicebox projects can attach arbitrary hook contracts (pay hooks, cashout hooks, 721 tier hooks, etc.) that execute during payments, cashouts, and payouts. A malicious hook could steal funds or mislead users. Frontends need a way to answer the question: "Was this hook deployed by a trusted deployer like `JB721TiersHookDeployer`?"
5
+ `nana-address-registry-v6` is a tiny trust-attestation primitive. It records who deployed a contract by recomputing the deployed address from CREATE or CREATE2 inputs and storing the verified deployer on-chain.
6
6
 
7
- `JBAddressRegistry` solves this by letting contracts deployed via `create` or `create2` publicly register their deployer's address. A frontend can then call `deployerOf(hookAddress)` and check the result against its own list of trusted deployers — displaying warnings or blocking interactions for hooks with unknown origins.
7
+ ## Boundaries
8
8
 
9
- ## Contract Map
9
+ - The repo does not assess contract safety.
10
+ - It does not manage upgrades, ownership, or deployment permissions.
11
+ - It only answers one question: "which deployer could have created this address?"
10
12
 
11
- ```
12
- src/
13
- ├── JBAddressRegistry.sol — Registry: registerAddress (create/create2), deployerOf mapping
14
- └── interfaces/
15
- └── IJBAddressRegistry.sol — Interface
16
- ```
17
-
18
- ## Key Operations
13
+ ## Main Components
19
14
 
20
- ### Registration (create)
21
- ```
22
- Deployer JBAddressRegistry.registerAddress(deployer, nonce)
23
- Compute address via RLP encoding of [deployer, nonce]
24
- → Store deployerOf[computedAddress] = deployer
25
- → Emit AddressRegistered
26
- ```
15
+ | Component | Responsibility |
16
+ | --- | --- |
17
+ | `JBAddressRegistry` | Verifies deterministic address derivation and stores `deployerOf[address]` |
18
+ | `IJBAddressRegistry` | Minimal public interface for registration and lookup |
27
19
 
28
- ### Registration (create2)
29
- ```
30
- Deployer → JBAddressRegistry.registerAddress(deployer, salt, bytecode)
31
- → Compute address via keccak256(0xff ++ deployer ++ salt ++ keccak256(bytecode))
32
- → Store deployerOf[computedAddress] = deployer
33
- → Emit AddressRegistered
34
- ```
20
+ ## Runtime Model
35
21
 
36
- ### Verification
37
- ```
38
- Frontend JBAddressRegistry.deployerOf(hookAddress)
39
- Returns deployer address (or address(0) if unregistered)
40
- Frontend checks deployer against trusted deployer list
22
+ ```text
23
+ caller
24
+ -> provides deployer plus CREATE nonce or CREATE2 salt+bytecode
25
+ -> registry recomputes the target address
26
+ -> registry stores the deployer for that address if it was not already registered
41
27
  ```
42
28
 
43
- ## Design Decisions
29
+ ## Critical Invariants
44
30
 
45
- **Deployer verification, not a whitelist.** The registry records *who* deployed a contract, not *whether* a contract is approved. This keeps the registry permissionless and neutral any deployer can register, and trust decisions are made by each frontend independently. There is no governance or admin role.
31
+ - Registration is permissionless because correctness comes from deterministic address derivation, not caller authority.
32
+ - Re-registration must stay impossible.
33
+ - CREATE and CREATE2 derivations must match EVM address derivation exactly; this repo is useless if the reconstruction is even slightly wrong.
46
34
 
47
- **Both `create` and `create2` support.** Deployers that use `create` (nonce-based) and `create2` (salt + bytecode) both exist in the Juicebox ecosystem. Supporting both ensures any deployer can register its contracts regardless of deployment strategy.
35
+ ## Where Complexity Lives
48
36
 
49
- **No validation beyond hash match.** The registry does not check that registered addresses contain code, implement a particular interface, or were recently deployed. It only verifies that the provided deployer + nonce/salt/bytecode deterministically produce the claimed address. This keeps the contract simple and gas-efficient — frontends already perform their own trust checks on the deployer address.
50
-
51
- **Anyone can call `registerAddress`.** Registration is not restricted to the deployer itself. Any account that knows the deployer address and nonce (or salt + bytecode) can register a contract. This is safe because the mapping is deterministic — providing incorrect inputs simply computes a different address, not a false registration for the target contract.
37
+ - Almost all of the risk is concentrated in a tiny amount of derivation logic.
38
+ - The repo is simple enough that overengineering is a bigger risk than underengineering.
52
39
 
53
40
  ## Dependencies
54
41
 
55
- - `@sphinx-labs/plugins` Deployment tooling (devDependency only)
42
+ - None that matter semantically beyond Solidity's address derivation rules
43
+
44
+ ## Safe Change Guide
56
45
 
57
- No runtime Solidity dependencies this is a standalone contract.
46
+ - Treat derivation logic as cryptographic plumbing. Prefer no change over clever change.
47
+ - If you touch nonce handling or bytecode hashing, add or retain tests for both CREATE and CREATE2 paths.
48
+ - Do not turn this registry into a trust oracle. Keep the scope narrow.
@@ -1,147 +1,52 @@
1
- # Audit Instructions -- nana-address-registry-v6
1
+ # Audit Instructions
2
2
 
3
- You are auditing a permissionless address registry for Juicebox V6. The contract stores a mapping from deployed contract addresses to their deployers, computed deterministically from `create` or `create2` parameters. It has no owner, no access control, no constructor arguments, and no external dependencies. Read [RISKS.md](./RISKS.md) first -- it documents all known risks and trust assumptions. Then come back here.
3
+ This repo is a small registry, but it participates in deployer verification across the ecosystem. Treat incorrect registration as a security boundary failure.
4
4
 
5
- ## Compiler and Version Info
5
+ ## Objective
6
6
 
7
- | Setting | Value |
8
- |---------|-------|
9
- | Solidity version | 0.8.28 |
10
- | EVM target | cancun |
11
- | Optimizer | enabled, 200 runs |
12
- | via-IR | not enabled |
13
- | Fuzz runs | 4,096 |
14
- | Invariant runs | 1,024 (depth 100) |
15
-
16
- Source: [`foundry.toml`](./foundry.toml)
17
-
18
- ## Previous Audit Findings
19
-
20
- A Nemesis automated audit was conducted on 2026-03-17. Results are in [`.audit/findings/nemesis-verified.md`](./.audit/findings/nemesis-verified.md). Summary:
21
-
22
- | ID | Severity | Title | Status |
23
- |----|----------|-------|--------|
24
- | NM-001 | LOW | Deployment library project name mismatch (`"nana-address-registry"` vs `"nana-address-registry-v6"`) | Open (deployment script only, no runtime impact) |
25
-
26
- The core contract (`JBAddressRegistry`) was verified sound -- RLP encoding is correct across all 10 nonce ranges, CREATE2 computation matches EIP-1014. No CRITICAL, HIGH, or MEDIUM findings were identified.
27
-
28
- No prior formal audit with finding IDs from an external security firm has been conducted.
7
+ Find issues that:
8
+ - let callers register contracts under the wrong deployer
9
+ - break determinism or uniqueness assumptions around registration
10
+ - let a malicious deployer spoof provenance for contracts it did not create
11
+ - create stale or truncation-related collisions in recorded mappings
29
12
 
30
13
  ## Scope
31
14
 
32
- **In scope -- all Solidity in `src/`:**
33
- ```
34
- src/JBAddressRegistry.sol # Registry implementation (~127 lines)
35
- src/interfaces/IJBAddressRegistry.sol # Interface (~27 lines)
36
- ```
37
-
38
- **Out of scope:** Test files, deployment scripts, forge-std.
39
-
40
- ## Architecture
41
-
42
- ### JBAddressRegistry
43
-
44
- A standalone, stateless-logic contract with a single storage mapping:
45
-
46
- ```
47
- mapping(address addr => address deployer) public deployerOf;
48
- ```
49
-
50
- Two public `registerAddress` overloads accept deployer parameters, compute the deterministic address, and store the mapping. No validation is performed beyond address computation and a nonce range check.
51
-
52
- ### Registration (create)
53
-
54
- `registerAddress(address deployer, uint256 nonce)`:
55
- 1. Calls `_addressFrom(deployer, nonce)` to compute the `create` address via RLP encoding
56
- 2. Stores `deployerOf[computedAddress] = deployer`
57
- 3. Emits `AddressRegistered(computedAddress, deployer, msg.sender)`
58
-
59
- ### Registration (create2)
60
-
61
- `registerAddress(address deployer, bytes32 salt, bytes calldata bytecode)`:
62
- 1. Computes `address(uint160(uint256(keccak256(abi.encodePacked(bytes1(0xff), deployer, salt, keccak256(bytecode))))))`
63
- 2. Stores `deployerOf[computedAddress] = deployer`
64
- 3. Emits `AddressRegistered(computedAddress, deployer, msg.sender)`
65
-
66
- ### RLP Encoding (_addressFrom)
67
-
68
- The internal `_addressFrom(address origin, uint256 nonce)` function implements RLP encoding of `[origin, nonce]` for `create` address computation. It handles 10 nonce ranges covering `0` through `type(uint64).max`:
69
-
70
- | Nonce Range | RLP Prefix Byte | Nonce Length Prefix |
71
- |-------------|----------------|---------------------|
72
- | `0` | `0xd6` | `0x80` (empty byte) |
73
- | `1 - 0x7f` | `0xd6` | (none, raw byte) |
74
- | `0x80 - 0xff` | `0xd7` | `0x81` |
75
- | `0x100 - 0xffff` | `0xd8` | `0x82` |
76
- | `0x10000 - 0xffffff` | `0xd9` | `0x83` |
77
- | `0x1000000 - 0xffffffff` | `0xda` | `0x84` |
78
- | `0x100000000 - 0xffffffffff` | `0xdb` | `0x85` |
79
- | `0x10000000000 - 0xffffffffffff` | `0xdc` | `0x86` |
80
- | `0x1000000000000 - 0xffffffffffffff` | `0xdd` | `0x87` |
81
- | `0x100000000000000 - 0xffffffffffffffff` | `0xde` | `0x88` |
82
-
83
- The final address is extracted from `keccak256(rlp_data)` via inline assembly: `mstore(0, hash); addr := mload(0)`.
84
-
85
- Nonces above `type(uint64).max` revert with `JBAddressRegistry_NonceTooLarge`.
86
-
87
- ## Priority Audit Areas
88
-
89
- ### 1. RLP Encoding Correctness (Highest Priority)
90
-
91
- The `_addressFrom` function is the only non-trivial logic in the contract. Verify:
92
-
93
- - **Every nonce range boundary is correct.** The if/else chain must produce correct RLP for every boundary value: `0`, `1`, `0x7f`, `0x80`, `0xff`, `0x100`, `0xffff`, `0x10000`, etc., up to `type(uint64).max`. An off-by-one at any boundary would silently produce wrong addresses.
94
- - **RLP prefix bytes are correct.** The first byte (`0xd6`-`0xde`) encodes the total length of the list. Verify each prefix matches the actual encoded data length (20-byte address + nonce encoding + overhead).
95
- - **Nonce encoding is correct.** For nonce `0`, the RLP encoding is `0x80` (empty byte string), not `0x00`. For nonces `1-0x7f`, the nonce IS the RLP encoding (single byte). For `0x80+`, a length prefix is prepended.
96
- - **Assembly address extraction.** The final `mstore(0, hash); addr := mload(0)` extracts the low 160 bits of the keccak256 hash. Verify this is equivalent to `address(uint160(uint256(hash)))`.
97
- - **Comparison with reference implementations.** Cross-check against the Ethereum Yellow Paper, OpenZeppelin's `Create2` library, and the linked StackExchange reference (https://ethereum.stackexchange.com/a/87840/68134).
98
-
99
- ### 2. create2 Address Computation
100
-
101
- The `create2` overload uses `abi.encodePacked(bytes1(0xff), deployer, salt, keccak256(bytecode))`. Verify:
102
- - This matches the EIP-1014 specification exactly.
103
- - The `bytes calldata bytecode` parameter is hashed correctly (constructor arguments must be included by the caller; the contract does not append them).
104
- - No length ambiguity in the packed encoding (each component has fixed size: 1 + 20 + 32 + 32 = 85 bytes).
105
-
106
- ### 3. Overwrite Behavior
107
-
108
- `_registerAddress` unconditionally overwrites `deployerOf[addr]`. Verify:
109
- - A re-registration with the same parameters produces the same result (idempotent).
110
- - A re-registration with different parameters that happen to compute the same address (collision) would overwrite. Since address collisions require a keccak256 collision, this is cryptographically infeasible -- but confirm there is no cheaper attack vector.
111
- - The `caller` field in the `AddressRegistered` event correctly reflects `msg.sender`, not the `deployer` parameter.
15
+ In scope:
16
+ - `src/JBAddressRegistry.sol`
17
+ - `src/interfaces/IJBAddressRegistry.sol`
18
+ - deployment scripts in `script/`
112
19
 
113
- ### 4. Gas and DoS
20
+ ## System Model
114
21
 
115
- The contract has no loops, no arrays, and no unbounded storage growth beyond the mapping. Verify:
116
- - `registerAddress` has bounded gas cost regardless of inputs.
117
- - The `bytecode` parameter in the `create2` overload is hashed in memory. For very large bytecode, this could consume significant memory gas but cannot cause an OOG in the registry itself (the caller pays).
22
+ The registry maps deployed addresses to the deployer that created them. Downstream repos use it to:
23
+ - validate provenance for clones or deterministically deployed instances
24
+ - discover whether a contract came from an approved deployer path
118
25
 
119
- ## Invariants to Verify
26
+ ## Critical Invariants
120
27
 
121
- 1. **Determinism**: For any `(deployer, nonce)` pair, `_addressFrom` always returns the same address, and that address matches what the EVM would produce for a `create` deployment from `deployer` at `nonce`.
122
- 2. **create2 correctness**: For any `(deployer, salt, bytecode)` triple, the computed address matches what the EVM would produce for a `create2` deployment.
123
- 3. **No side effects**: `registerAddress` only modifies `deployerOf[computedAddress]` and emits one event. No other state is touched.
124
- 4. **Nonce boundary completeness**: Every valid nonce (0 through `type(uint64).max`) produces a correct RLP encoding. No nonce in this range falls through without being encoded.
28
+ 1. Provenance cannot be forged
29
+ Only the actual deployer path the registry intends to trust may create a successful registration for a contract.
125
30
 
126
- ## Testing Setup
31
+ 2. One contract maps to one authoritative deployer record
32
+ No aliasing or overwrite path should let a later caller replace provenance unexpectedly.
127
33
 
128
- ```bash
129
- cd nana-address-registry-v6
130
- npm install
131
- forge build
132
- forge test
34
+ 3. Registration metadata is stable
35
+ Nonce, salt, or address truncation must not allow collisions or stale reads.
133
36
 
134
- # Run edge case tests
135
- forge test --match-contract JBAddressRegistryEdge -vvv
37
+ ## Threat Model
136
38
 
137
- # Run nonce truncation regression test
138
- forge test --match-path test/regression/NonceTruncation.t.sol -vvv
39
+ Prioritize:
40
+ - zero-address or malformed registration attempts
41
+ - deterministic deployment edge cases
42
+ - overwrite or replay behavior
43
+ - any assumption that `msg.sender` is sufficient proof without deployment linkage
139
44
 
140
- # Run fork tests
141
- forge test --match-contract Fork -vvv
45
+ ## Build And Verification
142
46
 
143
- # Write a PoC
144
- forge test --match-path test/audit/ExploitPoC.t.sol -vvv
145
- ```
47
+ Standard workflow:
48
+ - `npm install`
49
+ - `forge build`
50
+ - `forge test`
146
51
 
147
- Go break it.
52
+ Tests already focus on zero deployers and nonce-truncation regressions. A meaningful finding here should show downstream trust in the registry becoming misplaced, not just a cosmetic mismatch.
package/CHANGELOG.md ADDED
@@ -0,0 +1,39 @@
1
+ # Changelog
2
+
3
+ ## Scope
4
+
5
+ This file describes the verified change from `nana-address-registry-v5` to the current `nana-address-registry-v6` repo.
6
+
7
+ ## Current v6 surface
8
+
9
+ - `JBAddressRegistry`
10
+ - `IJBAddressRegistry`
11
+
12
+ ## Summary
13
+
14
+ - Nonce handling is safer than in v5. The registry now guards against oversized nonces instead of silently producing the wrong derived address once the old encoding assumptions stopped holding.
15
+ - Zero-address deployers are explicitly rejected.
16
+ - The external surface remains intentionally small. This repo changed behavior more than shape.
17
+ - The repo moved from the v5 Solidity baseline to `0.8.28`.
18
+
19
+ ## Verified deltas
20
+
21
+ - `_addressFrom(...)` now supports RLP nonce encoding through `uint64` instead of stopping at the old `uint32` path.
22
+ - `JBAddressRegistry_NonceTooLarge(uint256)` is thrown above that supported range.
23
+ - `JBAddressRegistry_ZeroDeployer()` is thrown when trying to register against `address(0)`.
24
+ - Duplicate registration now explicitly reverts with `JBAddressRegistry_AlreadyRegistered(address)`.
25
+
26
+ ## Breaking ABI changes
27
+
28
+ - There is no meaningful function-selector migration here.
29
+ - The practical ABI-visible change is new custom errors that callers and tooling may need to decode.
30
+
31
+ ## Indexer impact
32
+
33
+ - Event shape is effectively unchanged.
34
+ - The real migration concern is stricter revert behavior for previously tolerated bad inputs.
35
+
36
+ ## Migration notes
37
+
38
+ - If you treated this repo as ABI-stable, that is mostly still true, but behavior around bad inputs is stricter.
39
+ - Recheck any tool that depended on silent high-nonce behavior. v6 makes that path explicit instead of permissive.
package/README.md CHANGED
@@ -1,99 +1,77 @@
1
1
  # Juicebox Address Registry
2
2
 
3
- Knowing who deployed a contract is the first step toward trusting it. This registry lets anyone prove a contract's deployer on-chain -- no access control and no admin keys.
3
+ `@bananapus/address-registry-v6` is a permissionless registry that records which deployer created a contract. It is meant to make deployer provenance visible on-chain, especially for hooks and helper contracts that users may need to trust before interacting with them.
4
4
 
5
- `JBAddressRegistry` maps contract addresses to their deployers using deterministic address computation. Provide the deployer address and deployment parameters, and the registry verifies the relationship and stores it permanently. Frontend clients can then look up any registered contract to see who deployed it, which is especially useful for vetting Juicebox pay and cash-out hooks before interacting with them.
5
+ Architecture: [ARCHITECTURE.md](./ARCHITECTURE.md)
6
6
 
7
- ## Deployed Address
7
+ ## Overview
8
8
 
9
- `JBAddressRegistry` is deployed at the same address on all supported networks via deterministic `create2` deployment:
9
+ The registry supports both `create` and `create2` style deployments:
10
10
 
11
- ```
12
- 0x2d9b78cb37ca724cfb9b32cd8e9a5dc1c88bc7bb
13
- ```
14
-
15
- | Network | Chain ID |
16
- |---------|----------|
17
- | Ethereum | 1 |
18
- | Optimism | 10 |
19
- | Arbitrum | 42161 |
20
- | Base | 8453 |
21
- | Ethereum Sepolia | 11155111 |
22
- | Optimism Sepolia | 11155420 |
23
- | Arbitrum Sepolia | 421614 |
24
- | Base Sepolia | 84532 |
25
-
26
- ## Architecture
11
+ - for `create`, it reconstructs the deployed address from the deployer and nonce
12
+ - for `create2`, it reconstructs the deployed address from the deployer, salt, and deployment bytecode
27
13
 
28
- | Contract | Description |
29
- |----------|-------------|
30
- | `JBAddressRegistry` | Standalone registry. Computes deployed addresses deterministically from deployer parameters and stores the deployer in `deployerOf`. No constructor arguments, no access control, no external dependencies. |
14
+ Because the address is computed deterministically, registrations do not require access control. Anyone can submit the correct deployment inputs, and the registry records the verified deployer for the computed address.
31
15
 
32
- ### Interface
16
+ Use this repo when deployer provenance matters. Do not confuse it with an allowlist, audit registry, or trust oracle.
33
17
 
34
- | Type | Description |
35
- |------|-------------|
36
- | `IJBAddressRegistry` | Interface exposing `deployerOf`, both `registerAddress` overloads, and the `AddressRegistered` event. |
18
+ If the question is "is this hook safe?" this repo can only tell you who deployed it, not whether the code is good.
37
19
 
38
- ### How It Works
20
+ ## Key Contract
39
21
 
40
- Anyone can register a contract by providing its deployer and deployment parameters:
22
+ | Contract | Role |
23
+ | --- | --- |
24
+ | `JBAddressRegistry` | Standalone registry that stores `deployerOf[address]` and exposes overloaded `registerAddress` entrypoints. |
41
25
 
42
- - **`create` deployments**: Provide the deployer address and the nonce at the time of deployment. The registry reconstructs the address using RLP encoding (the same encoding the EVM uses internally to compute `create` addresses).
43
- - **`create2` deployments**: Provide the deployer address, the `create2` salt, and the full deployment bytecode (creation code + encoded constructor arguments). The registry computes `keccak256(0xff ++ deployer ++ salt ++ keccak256(bytecode))`.
26
+ ## Mental Model
44
27
 
45
- In both cases, the registry stores the mapping `deployerOf[computedAddress] = deployer` and emits an `AddressRegistered` event. Frontend clients can then look up any contract's deployer to verify trust.
28
+ The registry is intentionally narrow:
46
29
 
47
- No access control is needed -- only the correct deployer + parameters can produce a given address, so registrations cannot be faked.
30
+ 1. reconstruct an address from deployment inputs
31
+ 2. bind that address to a deployer once
32
+ 3. expose the result for other systems and clients
48
33
 
49
- ```solidity
50
- // Register a contract deployed via create.
51
- registry.registerAddress(deployer, nonce);
34
+ Anything beyond that is out of scope by design.
52
35
 
53
- // Register a contract deployed via create2.
54
- registry.registerAddress(deployer, salt, bytecode);
36
+ ## Install
55
37
 
56
- // Look up who deployed a contract.
57
- address deployer = registry.deployerOf(contractAddress);
38
+ ```bash
39
+ npm install @bananapus/address-registry-v6
58
40
  ```
59
41
 
60
- ### Events
61
-
62
- | Event | Fields | Emitted When |
63
- |-------|--------|-------------|
64
- | `AddressRegistered` | `address indexed addr`, `address indexed deployer`, `address caller` | A contract address is registered via either `registerAddress` overload. `caller` is `msg.sender`, which may differ from the deployer. |
65
-
66
- ### Risks
42
+ ## Development
67
43
 
68
- Hooks have token minting access, making malicious hooks dangerous. A registered deployer does not guarantee a hook is safe -- it only tells you who deployed it. Clients should warn project owners and users about any potential for unintended or adversarial behavior, especially for unknown hooks.
69
-
70
- Deployers can be exploited or act maliciously. Clients should still communicate risk to users even when the deployer is a known entity.
71
-
72
- ### Limitations
44
+ ```bash
45
+ npm install
46
+ forge build
47
+ forge test
48
+ ```
73
49
 
74
- - The `_addressFrom` function for `create` addresses uses RLP encoding that only supports nonces up to `uint64` max (18,446,744,073,709,551,615). Higher nonces revert with `JBAddressRegistry_NonceTooLarge`. In practice, this limit is unreachable.
75
- - Re-registration is prevented: registering the same computed address again reverts with `JBAddressRegistry_AlreadyRegistered`. Only the first registration is accepted.
76
- - Registration is permissionless -- anyone can call `registerAddress`, not just the deployer. Security relies entirely on deterministic address computation.
50
+ Useful scripts:
77
51
 
78
- ## Deployment
52
+ - `npm run test:fork`
53
+ - `npm run deploy:mainnets`
54
+ - `npm run deploy:testnets`
79
55
 
80
- The deploy script uses [Sphinx](https://github.com/sphinx-labs/sphinx) for deterministic multi-chain deployment. The registry is deployed via `create2` with the salt `_JBAddressRegistryV6_`, ensuring the same address on every chain. The script skips deployment if the bytecode is already present at the computed address.
56
+ ## Deployment Notes
81
57
 
82
- A helper library `AddressRegistryDeploymentLib` is provided in `script/helpers/` to resolve deployed addresses from Sphinx deployment artifacts at runtime.
58
+ The deploy script uses Sphinx for deterministic deployment. This package is intentionally small and independent because many other repos use it to record clone factories and helper deployments.
83
59
 
84
- ## Install
60
+ ## Repository Layout
85
61
 
86
- ```bash
87
- npm install
62
+ ```text
63
+ src/
64
+ JBAddressRegistry.sol
65
+ interfaces/
66
+ test/
67
+ unit, edge, fork, audit, and regression coverage
68
+ script/
69
+ Deploy.s.sol
70
+ helpers/
88
71
  ```
89
72
 
90
- ## Develop
73
+ ## Risks And Notes
91
74
 
92
- | Command | Description |
93
- |---------|-------------|
94
- | `forge build` | Compile contracts |
95
- | `forge test` | Run unit tests |
96
- | `FOUNDRY_PROFILE=CI forge test` | Run fork tests (requires `RPC_ETHEREUM_MAINNET` env var) |
97
- | `forge coverage --match-path "./src/*.sol" --report lcov --report summary` | Generate coverage report |
98
- | `npm run deploy:mainnets` | Propose mainnet deployment via Sphinx |
99
- | `npm run deploy:testnets` | Propose testnet deployment via Sphinx |
75
+ - provenance is not the same thing as safety; a known deployer can still deploy unsafe code
76
+ - registrations are first-write only, so bad operational processes around initial registration can be sticky
77
+ - the `create` address path relies on nonce reconstruction and intentionally rejects unrealistic nonce ranges
package/RISKS.md CHANGED
@@ -1,4 +1,21 @@
1
- # RISKS.md -- nana-address-registry-v6
1
+ # Juicebox Address Registry Risk Register
2
+
3
+ This file focuses on the registry's core promise: recording claimed deployer linkage for deterministically derived contracts. The main risks are misuse, incorrect assumptions about what registration means, and collisions between social trust and on-chain truth.
4
+
5
+ ## How to use this file
6
+
7
+ - Read `Priority risks` first; the biggest risks here are almost all interpretive, not balance-sheet failures.
8
+ - Use the detailed sections to distinguish what the registry proves from what users may incorrectly infer from it.
9
+ - Treat `Invariants to Verify` as the minimal safety envelope for deterministic registration.
10
+
11
+ ## Priority risks
12
+
13
+ | Priority | Risk | Why it matters | Primary controls |
14
+ |----------|------|----------------|------------------|
15
+ | P1 | Over-trusting registration as approval | The registry proves deployer linkage, not code safety or ecosystem endorsement. Users can still trust malicious deployments. | Clear docs, UI labeling, and strict separation between proof of origin and proof of safety. |
16
+ | P1 | Incorrect deployment-parameter assumptions | Deterministic verification is only as good as the deployment parameters supplied. Wrong assumptions create false negatives or confusing operator workflows. | Strong test coverage around CREATE and CREATE2 derivation and explicit documentation. |
17
+ | P2 | Registry completeness assumptions | Useful contracts may remain unregistered; absence from the registry is not proof of absence or malice. | Operational guidance for clients and integrators to treat registration as additive evidence only. |
18
+
2
19
 
3
20
  ## 1. Trust Assumptions
4
21