@bananapus/address-registry-v6 0.0.17 → 0.0.19

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
@@ -1,74 +1,67 @@
1
1
  # Administration
2
2
 
3
- Admin privileges and their scope in nana-address-registry-v6.
4
-
5
3
  ## At A Glance
6
4
 
7
5
  | 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
6
+ | --- | --- |
7
+ | Scope | Permissionless provenance registration for `CREATE` and `CREATE2` addresses |
8
+ | Control posture | Fully permissionless and adminless |
9
+ | Highest-risk actions | Incorrect first registration or bad derivation assumptions in offchain tooling |
10
+ | Recovery posture | No in-place recovery; replacement contract is the only fix for logic mistakes |
15
11
 
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.
12
+ ## Purpose
19
13
 
20
- ## One-Way Or High-Risk Actions
14
+ `nana-address-registry-v6` has no admin surface. It is a permissionless first-write provenance registry.
21
15
 
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.
16
+ ## Control Model
25
17
 
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.
18
+ - no owner
19
+ - no governance
20
+ - no pause
21
+ - no upgrade
22
+ - registration is permissionless and correctness comes from deterministic address derivation
30
23
 
31
24
  ## Roles
32
25
 
33
- None. `JBAddressRegistry` has no owner, no admin, and no access control. The contract does not inherit from `Ownable`, `AccessControl`, or any permissioned pattern.
26
+ | Role | How Assigned | Scope | Notes |
27
+ | --- | --- | --- | --- |
28
+ | Anyone | No assignment | Global | Can register an address if they provide correct `CREATE` or `CREATE2` inputs |
29
+
30
+ ## Privileged Surfaces
34
31
 
35
- ## Privileged Functions
32
+ There are no privileged functions. `registerAddress(...)` is permissionless for both registration paths.
36
33
 
37
- ### JBAddressRegistry
34
+ ## Immutable And One-Way
38
35
 
39
- | Function | Required Role | Permission ID | Scope | What It Does |
40
- |----------|--------------|---------------|-------|--------------|
41
- | `registerAddress(address deployer, uint256 nonce)` | None | N/A | Global | Computes a `create` address from deployer + nonce and stores the deployer mapping |
42
- | `registerAddress(address deployer, bytes32 salt, bytes bytecode)` | None | N/A | Global | Computes a `create2` address from deployer + salt + bytecode and stores the deployer mapping |
43
- | `deployerOf(address)` | None | N/A | Global | View function — returns the registered deployer for a given address |
36
+ - registration is first-write only
37
+ - there is no overwrite or delete path for `deployerOf[address]`
44
38
 
45
- Every function is callable by any address. There are no restricted operations.
39
+ ## Operational Notes
46
40
 
47
- ## Registration Model
41
+ - treat registration as provenance, not endorsement
42
+ - register addresses from trustworthy operational pipelines because bad first registration is sticky even though anyone can submit the correct derivation inputs
48
43
 
49
- - **Fully permissionless.** Any address can register any deployer/nonce or deployer/salt/bytecode combination.
50
- - **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.
51
- - **Overwritable.** A second registration for the same computed address overwrites the previous deployer mapping. Last writer wins.
52
- - **Permanent storage, no removal.** There is no `unregister` or `removeAddress` function. Entries can be overwritten but never deleted.
53
- - **No approval or queue.** Registrations take effect immediately in the same transaction.
44
+ ## Machine Notes
54
45
 
55
- ## Client-Side Trust
46
+ - do not treat registration as a safety certification or allowlist signal
47
+ - `src/JBAddressRegistry.sol` is the only control-relevant runtime file; there is no hidden owner path
48
+ - if offchain derivation and onchain registration disagree, resolve the derivation logic rather than assuming overwrite is possible
56
49
 
57
- The registry stores deployer mappings without making trust judgments. All trust decisions are delegated to clients:
50
+ ## Recovery
58
51
 
59
- - **No on-chain filtering.** The contract does not distinguish "trusted" from "untrusted" deployers. Clients must maintain their own allowlist of known deployer addresses and cross-reference against `deployerOf()`.
60
- - **Event-based discovery.** The contract emits an `AddressRegistered(address indexed addr, address indexed deployer, address caller)` event on every registration. Clients can monitor this event to discover new registrations in real time.
61
- - **Overwrite risk.** Since registrations are overwritable, a client that caches `deployerOf(addr)` at time T may see a different result at time T+1 if someone re-registers the same address with a different deployer/nonce or deployer/salt/bytecode combination. Clients should re-check at time of use rather than caching indefinitely.
62
- - **No validation of deployment.** The registry computes the expected address from the inputs but does not verify that a contract actually exists at that address. A registration can be created for an address that has not yet been deployed (or will never be deployed).
52
+ - there is no admin recovery surface
53
+ - if derivation logic were ever wrong, the contract would need replacement rather than intervention
63
54
 
64
55
  ## Admin Boundaries
65
56
 
66
- There are no admins. Specifically:
57
+ - nobody can curate allowlists, edit entries, or block registration
58
+ - nobody can use this registry to certify code safety
67
59
 
68
- - **No pause mechanism.** The registry cannot be paused or frozen.
69
- - **No upgrade path.** The contract is not proxied or upgradeable.
70
- - **No fee extraction.** The contract holds no funds and collects no fees.
71
- - **No blocklist.** No address can be prevented from registering.
72
- - **No migration.** There is no way to transfer state to a new registry contract.
60
+ ## Source Map
73
61
 
74
- 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.
62
+ - `src/JBAddressRegistry.sol`
63
+ - `src/interfaces/IJBAddressRegistry.sol`
64
+ - `script/Deploy.s.sol`
65
+ - `script/helpers/AddressRegistryDeploymentLib.sol`
66
+ - `test/JBAddressRegistry_Fork.t.sol`
67
+ - `test/regression/NonceTruncation.t.sol`
package/ARCHITECTURE.md CHANGED
@@ -2,47 +2,83 @@
2
2
 
3
3
  ## Purpose
4
4
 
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.
5
+ `nana-address-registry-v6` is a small provenance primitive. It records which deployer could have created a contract address by recomputing `CREATE` or `CREATE2` inputs and storing the verified result on-chain.
6
6
 
7
- ## Boundaries
7
+ ## System Overview
8
8
 
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?"
9
+ The repo is intentionally small. `JBAddressRegistry` accepts deterministic deployment inputs, reconstructs the resulting address, and records the deployer if that address has not already been registered. It does not judge code safety, manage upgrades, or gate deployments.
12
10
 
13
- ## Main Components
11
+ ## Core Invariants
14
12
 
15
- | Component | Responsibility |
16
- | --- | --- |
17
- | `JBAddressRegistry` | Verifies deterministic address derivation and stores `deployerOf[address]` |
18
- | `IJBAddressRegistry` | Minimal public interface for registration and lookup |
13
+ - registration is permissionless because correctness comes from deterministic derivation, not caller authority
14
+ - a contract address can only be registered once
15
+ - registration must fail until runtime code actually exists at the derived address
16
+ - `CREATE` and `CREATE2` derivation must match EVM rules exactly
19
17
 
20
- ## Runtime Model
18
+ ## Modules
19
+
20
+ | Module | Responsibility | Notes |
21
+ | --- | --- | --- |
22
+ | `JBAddressRegistry` | Address derivation and first-write provenance storage | Main contract |
23
+ | `IJBAddressRegistry` | Minimal lookup and registration interface | External surface |
24
+
25
+ ## Trust Boundaries
26
+
27
+ - the registry attests to deterministic provenance, not code quality
28
+ - it does not manage ownership, upgrades, or allowlists
29
+ - external systems may trust its recorded provenance, so derivation correctness is the whole product
30
+
31
+ ## Critical Flows
32
+
33
+ ### Register
21
34
 
22
35
  ```text
23
36
  caller
24
- -> provides deployer plus CREATE nonce or CREATE2 salt+bytecode
37
+ -> supplies deployer plus CREATE nonce or CREATE2 salt and bytecode
25
38
  -> registry recomputes the target address
26
- -> registry stores the deployer for that address if it was not already registered
39
+ -> registry records the deployer if the address was previously unregistered
27
40
  ```
28
41
 
29
- ## Critical Invariants
30
-
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.
34
-
35
- ## Where Complexity Lives
42
+ ## Accounting Model
36
43
 
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.
44
+ No economic accounting lives here. The only important state is `deployerOf[address]`.
39
45
 
40
- ## Dependencies
46
+ ## Security Model
41
47
 
42
- - None that matter semantically beyond Solidity's address derivation rules
48
+ - the risk is concentrated in a small amount of address-derivation logic
49
+ - the registry records the derived deployer, not the transaction caller
50
+ - overengineering is more dangerous than minimal, auditable derivation code
43
51
 
44
52
  ## Safe Change Guide
45
53
 
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.
54
+ - treat derivation code like cryptographic plumbing
55
+ - keep the undeployed-address check and first-write-only rule intact
56
+ - if nonce handling or bytecode hashing changes, keep `CREATE` and `CREATE2` tests aligned
57
+ - do not expand the repo into an allowlist or trust-oracle system
58
+
59
+ ## Canonical Checks
60
+
61
+ - `CREATE` and `CREATE2` derivation correctness:
62
+ `test/JBAddressRegistry.t.sol`
63
+ - edge-path validation and first-write behavior:
64
+ `test/JBAddressRegistryEdge.t.sol`
65
+ - pre-registration, frontrun, and undeployed-code defenses:
66
+ `test/audit/CodexFrontRunRegistrationDoS.t.sol`
67
+ - provenance abuse and zero-deployer edge cases:
68
+ `test/audit/CodexUnauthorizedRegistrar.t.sol`
69
+ `test/audit/ZeroDeployerRegistration.t.sol`
70
+
71
+ ## Source Map
72
+
73
+ - `src/JBAddressRegistry.sol`
74
+ - `src/interfaces/IJBAddressRegistry.sol`
75
+ - `test/JBAddressRegistry.t.sol`
76
+ - `test/JBAddressRegistryEdge.t.sol`
77
+ - `test/audit/CodexFrontRunRegistrationDoS.t.sol`
78
+ - `test/audit/CodexUnauthorizedRegistrar.t.sol`
79
+ - `test/audit/ZeroDeployerRegistration.t.sol`
80
+ - `test/regression/NonceTruncation.t.sol`
81
+ - `script/Deploy.s.sol`
82
+ - `script/helpers/AddressRegistryDeploymentLib.sol`
83
+ - `references/runtime.md`
84
+ - `references/operations.md`
@@ -1,52 +1,67 @@
1
1
  # Audit Instructions
2
2
 
3
- This repo is a small registry, but it participates in deployer verification across the ecosystem. Treat incorrect registration as a security boundary failure.
3
+ This repo is a small registry, but it sits on a deployer-verification boundary across the ecosystem. Treat incorrect registration as a security failure.
4
4
 
5
- ## Objective
5
+ ## Audit Objective
6
6
 
7
7
  Find issues that:
8
+
8
9
  - let callers register contracts under the wrong deployer
9
10
  - break determinism or uniqueness assumptions around registration
10
11
  - let a malicious deployer spoof provenance for contracts it did not create
11
- - create stale or truncation-related collisions in recorded mappings
12
+ - create truncation-related collisions or stale mapping assumptions
12
13
 
13
14
  ## Scope
14
15
 
15
16
  In scope:
17
+
16
18
  - `src/JBAddressRegistry.sol`
17
19
  - `src/interfaces/IJBAddressRegistry.sol`
18
- - deployment scripts in `script/`
20
+ - all deployment helpers in `script/`
21
+
22
+ ## Start Here
19
23
 
20
- ## System Model
24
+ 1. `src/JBAddressRegistry.sol`
25
+ 2. `script/Deploy.s.sol`
26
+
27
+ ## Security Model
21
28
 
22
29
  The registry maps deployed addresses to the deployer that created them. Downstream repos use it to:
30
+
23
31
  - validate provenance for clones or deterministically deployed instances
24
32
  - discover whether a contract came from an approved deployer path
25
33
 
26
- ## Critical Invariants
34
+ ## Roles And Privileges
35
+
36
+ | Role | Powers | How constrained |
37
+ |------|--------|-----------------|
38
+ | Deployer | Register contracts as its outputs | Must prove authentic deployment provenance |
39
+ | Registry reader | Trust provenance for privileged decisions | Must not observe spoofable or mutable history |
27
40
 
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.
41
+ ## Integration Assumptions
30
42
 
31
- 2. One contract maps to one authoritative deployer record
32
- No aliasing or overwrite path should let a later caller replace provenance unexpectedly.
43
+ | Dependency | Assumption | What breaks if wrong |
44
+ |------------|------------|----------------------|
45
+ | Approved deployers | Produce the addresses they claim | Downstream provenance gates become meaningless |
33
46
 
34
- 3. Registration metadata is stable
35
- Nonce, salt, or address truncation must not allow collisions or stale reads.
47
+ ## Critical Invariants
36
48
 
37
- ## Threat Model
49
+ 1. Provenance cannot be forged.
50
+ Only the actual deployer path the registry intends to trust may create a successful registration for a contract.
51
+ 2. One contract maps to one authoritative deployer record.
52
+ No aliasing or overwrite path should let a later caller replace provenance unexpectedly.
53
+ 3. Registration metadata is stable.
54
+ Nonce, salt, or address truncation must not allow collisions or stale reads.
38
55
 
39
- Prioritize:
56
+ ## Attack Surfaces
57
+
58
+ - registration entrypoints that rely on deployer provenance
59
+ - overwrite and replay paths
60
+ - deterministic deployment assumptions
40
61
  - 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
44
62
 
45
- ## Build And Verification
63
+ ## Verification
46
64
 
47
- Standard workflow:
48
65
  - `npm install`
49
66
  - `forge build`
50
67
  - `forge test`
51
-
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/README.md CHANGED
@@ -1,17 +1,22 @@
1
1
  # Juicebox Address Registry
2
2
 
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.
3
+ `@bananapus/address-registry-v6` is a permissionless registry that records deployer provenance for contracts when callers provide matching `create` or `create2` deployment inputs. 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
- Architecture: [ARCHITECTURE.md](./ARCHITECTURE.md)
5
+ Architecture: [ARCHITECTURE.md](./ARCHITECTURE.md)
6
+ User journeys: [USER_JOURNEYS.md](./USER_JOURNEYS.md)
7
+ Skills: [SKILLS.md](./SKILLS.md)
8
+ Risks: [RISKS.md](./RISKS.md)
9
+ Administration: [ADMINISTRATION.md](./ADMINISTRATION.md)
10
+ Audit instructions: [AUDIT_INSTRUCTIONS.md](./AUDIT_INSTRUCTIONS.md)
6
11
 
7
12
  ## Overview
8
13
 
9
- The registry supports both `create` and `create2` style deployments:
14
+ The registry supports both `create` and `create2` deployments:
10
15
 
11
16
  - for `create`, it reconstructs the deployed address from the deployer and nonce
12
17
  - for `create2`, it reconstructs the deployed address from the deployer, salt, and deployment bytecode
13
18
 
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.
19
+ Because the address is computed deterministically, registrations do not need access control. Anyone can submit the correct deployment inputs, and the registry records the deployer for the computed address after confirming code already exists there.
15
20
 
16
21
  Use this repo when deployer provenance matters. Do not confuse it with an allowlist, audit registry, or trust oracle.
17
22
 
@@ -31,7 +36,31 @@ The registry is intentionally narrow:
31
36
  2. bind that address to a deployer once
32
37
  3. expose the result for other systems and clients
33
38
 
34
- Anything beyond that is out of scope by design.
39
+ Anything beyond that is out of scope.
40
+
41
+ ## Read These Files First
42
+
43
+ 1. `src/JBAddressRegistry.sol`
44
+ 2. `test/JBAddressRegistry.t.sol`
45
+ 3. `test/JBAddressRegistryEdge.t.sol`
46
+ 4. `test/audit/CodexFrontRunRegistrationDoS.t.sol`
47
+
48
+ ## Integration Traps
49
+
50
+ - provenance is only useful if callers also know what the deployer is trusted for
51
+ - permissionless registration is intentional, so integrations should verify the computed inputs rather than assume caller authority
52
+ - `create` nonce reconstruction and `create2` salt-bytecode reconstruction are different trust paths and should be reasoned about separately
53
+
54
+ ## Where State Lives
55
+
56
+ - deployer provenance: `JBAddressRegistry`
57
+ - deployment truth: the target chain history and bytecode inputs outside this repo
58
+
59
+ ## High-Signal Tests
60
+
61
+ 1. `test/JBAddressRegistry.t.sol`
62
+ 2. `test/JBAddressRegistryEdge.t.sol`
63
+ 3. `test/audit/CodexUnauthorizedRegistrar.t.sol`
35
64
 
36
65
  ## Install
37
66
 
@@ -72,6 +101,11 @@ script/
72
101
 
73
102
  ## Risks And Notes
74
103
 
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
104
+ - provenance is not the same as safety; a known deployer can still deploy unsafe code
105
+ - registrations are first-write only, so bad initial registration is sticky
106
+ - the `create` path relies on nonce reconstruction and intentionally rejects unrealistic nonce ranges
107
+
108
+ ## For AI Agents
109
+
110
+ - Describe this repo as a provenance registry, not as an allowlist or safety oracle.
111
+ - Read the edge and audit tests before making claims about frontrunning or unauthorized registration.
package/RISKS.md CHANGED
@@ -1,42 +1,58 @@
1
1
  # Juicebox Address Registry Risk Register
2
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.
3
+ This file covers what `JBAddressRegistry` actually proves: deterministic address provenance claims. The main risk is not funds loss inside the registry. It is consumers reading too much into a registration entry.
4
4
 
5
- ## How to use this file
5
+ ## How To Use This File
6
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.
7
+ - Read `Priority risks` first. Most failures here are interpretation and integration failures.
8
+ - Distinguish "address can be derived from these inputs" from "this deployment is trusted."
9
+ - Treat `Invariants to verify` as the narrow correctness envelope of the registry itself.
10
10
 
11
- ## Priority risks
11
+ ## Priority Risks
12
12
 
13
13
  | Priority | Risk | Why it matters | Primary controls |
14
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
-
15
+ | P1 | Over-trusting registration as safety approval | A registered deployer mapping does not mean the contract is audited, canonical, or safe. | UIs should label registration as provenance evidence only. |
16
+ | P1 | First-writer capture of a valid provenance claim | The registry records the first valid claim for an address and never updates it. | Operational discipline for trusted deployers and curated allowlists for consumers. |
17
+ | P2 | Completeness assumptions | Unregistered contracts can still be legitimate; absence from the registry is not proof of malice. | Treat registry data as additive metadata, not an allowlist. |
19
18
 
20
19
  ## 1. Trust Assumptions
21
20
 
22
- - **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 deployer/nonce or deployer/salt/bytecode parameters.
23
- - **Frontend trust.** Frontends must maintain their own list of trusted deployers. The registry provides the mapping, not a trust judgment.
21
+ - **Deterministic address formulas are correct.** The contract trusts its `CREATE` and `CREATE2` derivation logic to match EVM semantics.
22
+ - **Consumers define trust externally.** The registry does not decide which deployers are trusted.
24
23
 
25
24
  ## 2. Known Risks
26
25
 
27
- - **False registration.** Anyone can call `registerAddress` with arbitrary deployer/nonce values, registering a computed address with a deployer that did not actually deploy it. Consumers must verify the deployer is trusted, not just that a mapping exists.
28
- - **No removal mechanism.** Once registered, an entry cannot be removed. Re-registration of the same address reverts with `JBAddressRegistry_AlreadyRegistered`.
29
- - **CREATE2 vs CREATE1 trust model.** CREATE1 registrations (`registerAddress(deployer, nonce)`) can be spoofed: anyone who knows the deployer address and nonce can register the computed address without being the deployer. CREATE2 registrations (`registerAddress(deployer, salt, bytecode)`) have the same trust model — knowing the parameters is sufficient to register. The function accepts raw deployment bytecode and hashes it internally (`keccak256(bytecode)`) for the CREATE2 address computation. In both cases, the registry only proves "this address COULD have been deployed by this deployer with these parameters", not "this deployer DID deploy this address". Consumers must verify the deployer is trusted independently.
30
- - **Frontend trust example.** A malicious actor could register `deployerOf[uniswapRouter] = attackerDeployer` if they find a `(deployer, nonce)` or `(deployer, salt, bytecode)` combination that computes to the Uniswap router address and register it before the legitimate deployer does. Only the first registration is accepted; subsequent attempts revert with `JBAddressRegistry_AlreadyRegistered`. Frontends that display "deployed by X" based on `deployerOf` should cross-reference against a curated allowlist of trusted deployers.
26
+ - **Caller identity is irrelevant.** Anyone may call `registerAddress(...)`. The registry proves that an address matches supplied deployment parameters, not that the caller was the deployer.
27
+ - **First registration wins.** Once `deployerOf[addr]` is set, later registrations revert.
28
+ - **No pre-registration of future deployments.** `registerAddress(...)` requires code to already exist at the computed address.
29
+ - **No removal or correction path.** The registry is intentionally append-only per address.
30
+ - **Registration is provenance, not endorsement.** `deployerOf[hook] = someFactory` says nothing about code safety, upgradeability, audit status, or whether the deployer itself is trustworthy.
31
+ - **Operational lag matters.** If a trusted deployer forgets to register immediately, someone else can publish the first valid claim for that address.
32
+
33
+ ## 3. Integration Risks
34
+
35
+ - **Frontends should pair registry data with a trusted-deployer set.** Displaying `deployerOf` alone can mislead users into treating any registered provenance as official.
36
+ - **`CREATE` and `CREATE2` claims are parameter-based.** In either mode, the right mental model is "the address is compatible with these inputs," not "the registry witnessed deployment."
37
+ - **Off-chain explorers should preserve uncertainty.** "Registered deployer claim" is a safer label than "deployed by" unless the explorer also verified chain history.
38
+
39
+ ## 4. Invariants To Verify
40
+
41
+ - `deployerOf[addr]` is set at most once
42
+ - `CREATE` registrations only succeed for addresses derivable from the provided `(deployer, nonce)`
43
+ - `CREATE2` registrations only succeed for addresses derivable from the provided `(deployer, salt, bytecode)`
44
+ - `_addressFrom` remains correct for the supported nonce range and reverts outside that range
45
+
46
+ ## 5. Accepted Behaviors
47
+
48
+ ### 5.1 The registry does not authenticate the registrant
31
49
 
32
- ## 3. Invariants to Verify
50
+ This is intentional. `JBAddressRegistry` is a deterministic provenance registry, not a permissioned attestation service.
33
51
 
34
- - `deployerOf[addr]` always corresponds to a valid deployer/nonce pair that produces `addr` (if registered via `registerAddress`).
35
- - `create2` registrations: `deployerOf[addr]` corresponds to a valid deployer/salt/bytecode combination whose `keccak256(bytecode)` produces `addr` via the CREATE2 formula.
36
- - Registration idempotency: `deployerOf[addr]` reflects the first and only registration. Subsequent attempts to register the same address revert with `JBAddressRegistry_AlreadyRegistered`.
52
+ ### 5.2 Unregistered does not mean unsafe
37
53
 
38
- ## 4. Accepted Behaviors
54
+ The registry is useful metadata, but it does not cover every legitimate deployment. Consumers should not infer that an unregistered address is malicious just because no entry exists.
39
55
 
40
- ### 4.1 RLP encoding correctness is well-tested and bounded
56
+ ### 5.3 The registry is retrospective, not a reservation layer
41
57
 
42
- The `_addressFrom` function manually implements RLP encoding for nonces up to uint64. The nonce is capped at uint64 max with an explicit revert, and the encoding logic is a well-tested pattern. This is not an open risk.
58
+ This is intentional. A deterministic address can only be registered after code already exists there. Consumers should not expect `JBAddressRegistry` to signal future deployment intent or protect an undeployed `CREATE2` address from later first-writer capture.
package/SKILLS.md CHANGED
@@ -3,7 +3,7 @@
3
3
  ## Use This File For
4
4
 
5
5
  - Use this file when the task involves deployer provenance, `create` or `create2` registration logic, or determining what the registry does and does not prove.
6
- - Start here, then open the registry contract or tests that match the registration mode under review.
6
+ - Start here, then decide whether the issue is `create` address derivation, `create2` derivation, or misuse of provenance as a trust signal.
7
7
 
8
8
  ## Read This Next
9
9
 
@@ -11,8 +11,9 @@
11
11
  |---|---|
12
12
  | Repo overview and intended guarantees | [`README.md`](./README.md), [`ARCHITECTURE.md`](./ARCHITECTURE.md) |
13
13
  | Registry implementation | [`src/JBAddressRegistry.sol`](./src/JBAddressRegistry.sol) |
14
+ | Runtime and operational assumptions | [`references/runtime.md`](./references/runtime.md), [`references/operations.md`](./references/operations.md) |
14
15
  | Interfaces and deployment | [`src/interfaces/`](./src/interfaces/), [`script/Deploy.s.sol`](./script/Deploy.s.sol) |
15
- | Edge, fork, or regression coverage | [`test/JBAddressRegistry.t.sol`](./test/JBAddressRegistry.t.sol), [`test/JBAddressRegistryEdge.t.sol`](./test/JBAddressRegistryEdge.t.sol), [`test/regression/`](./test/regression/) |
16
+ | Edge and fork coverage | [`test/JBAddressRegistry.t.sol`](./test/JBAddressRegistry.t.sol), [`test/JBAddressRegistryEdge.t.sol`](./test/JBAddressRegistryEdge.t.sol), [`test/JBAddressRegistry_Fork.t.sol`](./test/JBAddressRegistry_Fork.t.sol) |
16
17
 
17
18
  ## Repo Map
18
19
 
@@ -30,10 +31,11 @@ Permissionless on-chain provenance registry that records which deployer created
30
31
  ## Reference Files
31
32
 
32
33
  - Open [`references/runtime.md`](./references/runtime.md) when you need the core guarantees, first-write semantics, or the difference between provenance and trust.
33
- - Open [`references/operations.md`](./references/operations.md) when you need deployment breadcrumbs, test pointers, or the common stale assumptions around what the registry can verify.
34
+ - Open [`references/operations.md`](./references/operations.md) when you need deployment breadcrumbs, test pointers, or common stale assumptions about what the registry can verify.
34
35
 
35
36
  ## Working Rules
36
37
 
37
38
  - Start in [`src/JBAddressRegistry.sol`](./src/JBAddressRegistry.sol). This repo is intentionally small, so most questions should collapse quickly to the core contract.
38
39
  - Treat provenance and safety as separate questions. The registry only proves who deployed something.
40
+ - Registration is first-write only and requires code to already exist at the computed address.
39
41
  - When a task involves wrong or missing registry data, verify the registration inputs before assuming a contract bug.
package/USER_JOURNEYS.md CHANGED
@@ -1,43 +1,90 @@
1
1
  # User Journeys
2
2
 
3
- ## Who This Repo Serves
3
+ ## Repo Purpose
4
4
 
5
- - deployers that want on-chain provenance for helper contracts and hooks
6
- - integrators checking who deployed an existing address
7
- - auditors verifying deterministic deployment claims
5
+ This repo records deployer provenance for contracts whose address can be reconstructed from `create` or `create2` inputs. It does not say whether a deployment is safe, canonical, or approved. It only says who deployed it when the inputs are correct and someone registered them.
6
+
7
+ ## Primary Actors
8
+
9
+ - deployers who want onchain provenance for hooks, clones, and helper contracts
10
+ - integrators who need to verify who deployed an address before trusting it
11
+ - auditors who want a deterministic provenance check instead of offchain screenshots
12
+
13
+ ## Key Surfaces
14
+
15
+ - `JBAddressRegistry`: stores `deployerOf[address]` after reconstructing the target address from deployment inputs
16
+ - `registerAddress(deployer, nonce)` and `registerAddress(deployer, salt, bytecode)`: the two provenance-registration paths
8
17
 
9
18
  ## Journey 1: Register A `CREATE` Deployment
10
19
 
11
- **Starting state:** you know the deploying address and nonce for a contract already created with `create`.
20
+ **Actor:** deployer, operator, or auditor with the original deployment inputs.
21
+
22
+ **Intent:** bind an already-deployed `create` address to the account that deployed it.
23
+
24
+ **Preconditions**
25
+ - the contract was deployed with `create`
26
+ - the caller knows the deployer address and nonce used for the deployment
27
+ - the address has not already been registered
12
28
 
13
- **Success:** the registry stores the verified deployer for the computed contract address.
29
+ **Main Flow**
30
+ 1. Call `registerAddress(deployer, nonce)`.
31
+ 2. `JBAddressRegistry` reconstructs the deployed address from the deployer and nonce.
32
+ 3. If the computed address is valid and unused, the registry stores `deployerOf[address] = deployer`.
14
33
 
15
- **Flow**
16
- 1. Call the `registerAddress` overload for `create` deployments with the deployer and nonce.
17
- 2. `JBAddressRegistry` reconstructs the expected deployed address.
18
- 3. If the reconstruction matches a real address and no one registered it before, the registry stores `deployerOf[address]`.
34
+ **Failure Modes**
35
+ - the nonce does not match the real deployment
36
+ - the computed address has already been registered
37
+ - the nonce exceeds the supported `uint64` range and registration reverts
38
+ - the deployment assumptions are wrong and the reconstructed address is useless
19
39
 
20
40
  ## Journey 2: Register A `CREATE2` Deployment
21
41
 
22
- **Starting state:** you know the deployer, salt, and init code for a deterministic deployment.
42
+ **Actor:** deployer, operator, or auditor with the original deterministic deployment inputs.
23
43
 
24
- **Success:** the registry records the verified deployer for the deterministic address without any privileged access.
44
+ **Intent:** bind a `create2` deployment to its deployer without privileged access.
25
45
 
26
- **Flow**
27
- 1. Call the `registerAddress` overload for `create2`.
28
- 2. The registry hashes deployer, salt, and deployment bytecode to reconstruct the deterministic address.
29
- 3. It stores the deployer for that address if the registration is valid and unused.
46
+ **Preconditions**
47
+ - the contract was deployed with `create2`
48
+ - the caller knows the deployer, salt, and init code
49
+ - the address has not already been registered
50
+
51
+ **Main Flow**
52
+ 1. Call `registerAddress(deployer, salt, bytecode)`.
53
+ 2. The registry reconstructs the deterministic address from the standard `create2` formula.
54
+ 3. If the address is valid and unused, the registry records the deployer.
55
+
56
+ **Failure Modes**
57
+ - the bytecode or salt is wrong
58
+ - the address was registered already
59
+ - a third party publishes the first valid provenance claim before the expected deployer registers it
60
+ - operators assume registration proves a contract exists there right now
61
+ - consumers misread provenance as an allowlist or audit stamp
30
62
 
31
63
  ## Journey 3: Resolve Provenance For An Existing Address
32
64
 
33
- **Starting state:** an integration or auditor sees a contract address and wants to know who deployed it.
65
+ **Actor:** integrator, frontend, or auditor.
66
+
67
+ **Intent:** answer "who deployed this?" before trusting a hook, helper, or clone.
68
+
69
+ **Preconditions**
70
+ - the address was registered previously
71
+ - the caller understands that an empty result means "unknown" rather than "unsafe"
72
+
73
+ **Main Flow**
74
+ 1. Query `deployerOf[address]`.
75
+ 2. If a deployer is present, use it as provenance evidence for who originated the deployment.
76
+ 3. If no deployer is present, treat the address as unregistered and keep investigating elsewhere.
77
+ 4. Pair the result with an external trust list, transaction history, or audit context before relying on the contract.
78
+
79
+ **Postconditions**
80
+ - downstream reviewers know which deployer or factory to inspect next
81
+ - the trust decision still happens outside this repo
34
82
 
35
- **Success:** the caller can query `deployerOf[address]` and get provenance if someone registered it correctly.
83
+ ## Trust Boundaries
36
84
 
37
- **Flow**
38
- 1. Look up the address in the registry.
39
- 2. If a deployer is present, use that as provenance evidence for who originated the deployment.
40
- 3. Treat absence as "not registered," not as a trust verdict on the code.
85
+ - this repo only proves registered deployer provenance from deterministic inputs
86
+ - anyone can submit a valid claim, so the mapping authenticates deployment inputs rather than caller identity
87
+ - it does not prove code quality, audit status, or governance approval
41
88
 
42
89
  ## Hand-Offs
43
90
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bananapus/address-registry-v6",
3
- "version": "0.0.17",
3
+ "version": "0.0.19",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
@@ -5,8 +5,10 @@
5
5
  - If you edit `create` reconstruction logic, verify nonce-boundary behavior.
6
6
  - If you edit `create2` behavior, verify bytecode hashing and salt assumptions.
7
7
  - If a user asks whether a contract is "safe," redirect the question to code provenance plus code review, not the registry alone.
8
+ - If you change registration guards, re-read the audit tests before trusting a narrower unit proof.
8
9
 
9
10
  ## Common Failure Modes
10
11
 
11
12
  - Operators confuse deployer provenance with trustworthiness.
12
13
  - Registration is attempted with stale deployment inputs from another repo or environment.
14
+ - The wrong party is allowed to bind or front-run a computed address because the first-write assumption was weakened.
@@ -15,3 +15,5 @@
15
15
  - [`test/JBAddressRegistry.t.sol`](../test/JBAddressRegistry.t.sol) for baseline behavior.
16
16
  - [`test/JBAddressRegistryEdge.t.sol`](../test/JBAddressRegistryEdge.t.sol) for boundary conditions.
17
17
  - [`test/JBAddressRegistry_Fork.t.sol`](../test/JBAddressRegistry_Fork.t.sol) for live assumptions.
18
+ - [`test/regression/NonceTruncation.t.sol`](../test/regression/NonceTruncation.t.sol) for nonce-width and reconstruction regressions.
19
+ - [`test/audit/ZeroDeployerRegistration.t.sol`](../test/audit/ZeroDeployerRegistration.t.sol), [`test/audit/CodexUnauthorizedRegistrar.t.sol`](../test/audit/CodexUnauthorizedRegistrar.t.sol), and [`test/audit/CodexFrontRunRegistrationDoS.t.sol`](../test/audit/CodexFrontRunRegistrationDoS.t.sol) for the abuse cases this repo is expected to resist.