@bananapus/address-registry-v6 0.0.25 → 0.0.26

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/ARCHITECTURE.md CHANGED
@@ -47,7 +47,7 @@ No economic accounting lives here. The only important state is `deployerOf[addre
47
47
 
48
48
  - the risk is concentrated in a small amount of address-derivation logic
49
49
  - the registry records the derived deployer, not the transaction caller
50
- - overengineering is more dangerous than minimal, auditable derivation code
50
+ - overengineering is more dangerous than minimal, reviewable derivation code
51
51
 
52
52
  ## Safe Change Guide
53
53
 
@@ -63,10 +63,10 @@ No economic accounting lives here. The only important state is `deployerOf[addre
63
63
  - edge-path validation and first-write behavior:
64
64
  `test/JBAddressRegistryEdge.t.sol`
65
65
  - pre-registration, frontrun, and undeployed-code defenses:
66
- `test/audit/CodexFrontRunRegistrationDoS.t.sol`
66
+ `test/regression/RegressionFrontRunRegistrationDoS.t.sol`
67
67
  - provenance abuse and zero-deployer edge cases:
68
- `test/audit/CodexUnauthorizedRegistrar.t.sol`
69
- `test/audit/ZeroDeployerRegistration.t.sol`
68
+ `test/regression/RegressionUnauthorizedRegistrar.t.sol`
69
+ `test/regression/ZeroDeployerRegistration.t.sol`
70
70
 
71
71
  ## Source Map
72
72
 
@@ -74,9 +74,9 @@ No economic accounting lives here. The only important state is `deployerOf[addre
74
74
  - `src/interfaces/IJBAddressRegistry.sol`
75
75
  - `test/JBAddressRegistry.t.sol`
76
76
  - `test/JBAddressRegistryEdge.t.sol`
77
- - `test/audit/CodexFrontRunRegistrationDoS.t.sol`
78
- - `test/audit/CodexUnauthorizedRegistrar.t.sol`
79
- - `test/audit/ZeroDeployerRegistration.t.sol`
77
+ - `test/regression/RegressionFrontRunRegistrationDoS.t.sol`
78
+ - `test/regression/RegressionUnauthorizedRegistrar.t.sol`
79
+ - `test/regression/ZeroDeployerRegistration.t.sol`
80
80
  - `test/regression/NonceTruncation.t.sol`
81
81
  - `script/Deploy.s.sol`
82
82
  - `script/helpers/AddressRegistryDeploymentLib.sol`
@@ -4,7 +4,9 @@ This repo is a small registry, but it sits on a deployer-verification boundary a
4
4
 
5
5
  ## Audit Objective
6
6
 
7
- Find issues that:
7
+ There is a billion dollars of well-meaning projects' money in the Juicebox Money Engine, growing exponentially. Your job is to hack it before anyone else. Whoever hacks it first saves/steals the money, and you are obsessed with being this winner, while also being a steward of the protocol and wanting it to keep growing safely.
8
+
9
+ Suggestions of where to look:
8
10
 
9
11
  - let callers register contracts under the wrong deployer
10
12
  - break determinism or uniqueness assumptions around registration
package/README.md CHANGED
@@ -18,7 +18,7 @@ The registry supports both `create` and `create2` deployments:
18
18
 
19
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.
20
20
 
21
- Use this repo when deployer provenance matters. Do not confuse it with an allowlist, audit registry, or trust oracle.
21
+ Use this repo when deployer provenance matters. Do not confuse it with an allowlist, review registry, or trust oracle.
22
22
 
23
23
  If the question is "is this hook safe?" this repo can only tell you who deployed it, not whether the code is good.
24
24
 
@@ -43,7 +43,7 @@ Anything beyond that is out of scope.
43
43
  1. `src/JBAddressRegistry.sol`
44
44
  2. `test/JBAddressRegistry.t.sol`
45
45
  3. `test/JBAddressRegistryEdge.t.sol`
46
- 4. `test/audit/CodexFrontRunRegistrationDoS.t.sol`
46
+ 4. `test/regression/RegressionFrontRunRegistrationDoS.t.sol`
47
47
 
48
48
  ## Integration Traps
49
49
 
@@ -60,7 +60,7 @@ Anything beyond that is out of scope.
60
60
 
61
61
  1. `test/JBAddressRegistry.t.sol`
62
62
  2. `test/JBAddressRegistryEdge.t.sol`
63
- 3. `test/audit/CodexUnauthorizedRegistrar.t.sol`
63
+ 3. `test/regression/RegressionUnauthorizedRegistrar.t.sol`
64
64
 
65
65
  ## Install
66
66
 
@@ -93,7 +93,7 @@ src/
93
93
  JBAddressRegistry.sol
94
94
  interfaces/
95
95
  test/
96
- unit, edge, fork, audit, and regression coverage
96
+ unit, edge, fork, review, and regression coverage
97
97
  script/
98
98
  Deploy.s.sol
99
99
  helpers/
@@ -108,4 +108,4 @@ script/
108
108
  ## For AI Agents
109
109
 
110
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.
111
+ - Read the edge and review tests before making claims about frontrunning or unauthorized registration.
package/RISKS.md CHANGED
@@ -12,7 +12,7 @@ This file covers what `JBAddressRegistry` actually proves: deterministic address
12
12
 
13
13
  | Priority | Risk | Why it matters | Primary controls |
14
14
  |----------|------|----------------|------------------|
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. |
15
+ | P1 | Over-trusting registration as safety approval | A registered deployer mapping does not mean the contract is reviewed, canonical, or safe. | UIs should label registration as provenance evidence only. |
16
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
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. |
18
18
 
@@ -27,7 +27,7 @@ This file covers what `JBAddressRegistry` actually proves: deterministic address
27
27
  - **First registration wins.** Once `deployerOf[addr]` is set, later registrations revert.
28
28
  - **No pre-registration of future deployments.** `registerAddress(...)` requires code to already exist at the computed address.
29
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.
30
+ - **Registration is provenance, not endorsement.** `deployerOf[hook] = someFactory` says nothing about code safety, upgradeability, review status, or whether the deployer itself is trustworthy.
31
31
  - **Operational lag matters.** If a trusted deployer forgets to register immediately, someone else can publish the first valid claim for that address.
32
32
 
33
33
  ## 3. Integration Risks
package/STYLE_GUIDE.md CHANGED
@@ -451,54 +451,9 @@ jobs:
451
451
  run: forge fmt --check
452
452
  ```
453
453
 
454
- **slither.yml** (repos with `src/` contracts only):
455
- ```yaml
456
- name: slither
457
- on:
458
- pull_request:
459
- branches:
460
- - main
461
- push:
462
- branches:
463
- - main
464
- jobs:
465
- analyze:
466
- runs-on: ubuntu-latest
467
- steps:
468
- - uses: actions/checkout@v4
469
- with:
470
- submodules: recursive
471
- - uses: actions/setup-node@v4
472
- with:
473
- node-version: 25.9.0
474
- - name: Install npm dependencies
475
- run: npm install --omit=dev
476
- - name: Install Foundry
477
- uses: foundry-rs/foundry-toolchain@v1
478
- - name: Run slither
479
- uses: crytic/slither-action@v0.4.1
480
- with:
481
- slither-config: slither-ci.config.json
482
- fail-on: medium
483
- ```
484
-
485
- **slither-ci.config.json:**
486
- ```json
487
- {
488
- "detectors_to_exclude": "timestamp,uninitialized-local,naming-convention,solc-version,shadowing-local",
489
- "exclude_informational": true,
490
- "exclude_low": false,
491
- "exclude_medium": false,
492
- "exclude_high": false,
493
- "disable_color": false,
494
- "filter_paths": "(mocks/|test/|node_modules/|lib/)",
495
- "legacy_ast": false
496
- }
497
- ```
454
+ **Static review workflow** (repos with `src/` contracts only):
498
455
 
499
- **Variations:**
500
- - Deployer-only repos (no `src/`, only `script/`) skip slither entirely — the action's internal `forge build` skips `test/` and `script/` by default, leaving nothing to compile.
501
- - Use inline `// slither-disable-next-line <detector>` to suppress known false positives rather than adding to `detectors_to_exclude` in the config. The comment must be on the line immediately before the flagged expression.
456
+ Keep repo-local static review automation current with the package's runtime surface. At minimum, CI should run formatting, linting, and build checks with `--deny notes`. Repos that only contain deployment scripts can rely on the shared formatting and lint jobs unless they add runtime contracts.
502
457
 
503
458
  ### package.json
504
459
 
package/foundry.toml CHANGED
@@ -1,5 +1,6 @@
1
1
  [profile.default]
2
2
  solc = '0.8.28'
3
+ bytecode_hash = "none"
3
4
  evm_version = 'cancun'
4
5
  optimizer_runs = 200
5
6
  libs = ["node_modules", "lib"]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bananapus/address-registry-v6",
3
- "version": "0.0.25",
3
+ "version": "0.0.26",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
@@ -5,7 +5,7 @@
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
+ - If you change registration guards, re-read the review tests before trusting a narrower unit proof.
9
9
 
10
10
  ## Common Failure Modes
11
11
 
@@ -16,4 +16,4 @@
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
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.
19
+ - [`test/regression/ZeroDeployerRegistration.t.sol`](../test/regression/ZeroDeployerRegistration.t.sol), [`test/regression/RegressionUnauthorizedRegistrar.t.sol`](../test/regression/RegressionUnauthorizedRegistrar.t.sol), and [`test/regression/RegressionFrontRunRegistrationDoS.t.sol`](../test/regression/RegressionFrontRunRegistrationDoS.t.sol) for the abuse cases this repo is expected to resist.
@@ -10,7 +10,7 @@ contract Deploy is Script, Sphinx {
10
10
  bytes32 constant ADDRESS_REGISTRY_SALT = "_JBAddressRegistryV6_";
11
11
 
12
12
  function configureSphinx() public override {
13
- // TODO: Update to contain JB Emergency Developers
13
+ // Safe owners and threshold are resolved by the Sphinx project config.
14
14
  sphinxConfig.projectName = "nana-address-registry-v6";
15
15
  sphinxConfig.mainnets = ["ethereum", "optimism", "base", "arbitrum"];
16
16
  sphinxConfig.testnets = ["ethereum_sepolia", "optimism_sepolia", "base_sepolia", "arbitrum_sepolia"];
@@ -19,11 +19,10 @@ library AddressRegistryDeploymentLib {
19
19
  Vm internal constant vm = Vm(VM_ADDRESS);
20
20
 
21
21
  function getDeployment(string memory path) internal returns (AddressRegistryDeployment memory deployment) {
22
- // get chainId for which we need to get the deployment.
22
+ // Match the current chain ID to the Sphinx network name used in deployment artifacts.
23
23
  uint256 chainId = block.chainid;
24
24
 
25
- // Deploy to get the constants.
26
- // TODO: get constants without deploy.
25
+ // `SphinxConstants` exposes Sphinx's supported chain ID to network name mapping.
27
26
  SphinxConstants sphinxConstants = new SphinxConstants();
28
27
  NetworkInfo[] memory networks = sphinxConstants.getNetworkInfoArray();
29
28
 
@@ -22,7 +22,8 @@ contract JBAddressRegistry is IJBAddressRegistry {
22
22
  error JBAddressRegistry_NonceTooLarge(uint256 nonce);
23
23
 
24
24
  /// @notice Thrown when attempting to register with `address(0)` as the deployer.
25
- error JBAddressRegistry_ZeroDeployer();
25
+ /// @param deployer The invalid deployer address.
26
+ error JBAddressRegistry_ZeroDeployer(address deployer);
26
27
 
27
28
  /// @notice Thrown when attempting to register an address before code exists there.
28
29
  /// @param addr The undeployed address being registered.
@@ -80,7 +81,7 @@ contract JBAddressRegistry is IJBAddressRegistry {
80
81
  /// @param deployer The deployer's address.
81
82
  function _registerAddress(address addr, address deployer) internal {
82
83
  // The registry only records non-zero deployers.
83
- if (deployer == address(0)) revert JBAddressRegistry_ZeroDeployer();
84
+ if (deployer == address(0)) revert JBAddressRegistry_ZeroDeployer(deployer);
84
85
  // The address must already contain runtime code before it can be registered.
85
86
  if (addr.code.length == 0) revert JBAddressRegistry_AddressNotDeployed(addr);
86
87
  // Each address can only be registered once.
@@ -239,13 +239,13 @@ contract JBAddressRegistryEdge is Test {
239
239
 
240
240
  /// @notice Registration with address(0) as deployer reverts with `ZeroDeployer`.
241
241
  function test_zeroAddressDeployer_reverts() public {
242
- vm.expectRevert(JBAddressRegistry.JBAddressRegistry_ZeroDeployer.selector);
242
+ vm.expectRevert(abi.encodeWithSelector(JBAddressRegistry.JBAddressRegistry_ZeroDeployer.selector, address(0)));
243
243
  registry.registerAddress(address(0), 1);
244
244
  }
245
245
 
246
246
  /// @notice Create2 registration with address(0) as deployer reverts with `ZeroDeployer`.
247
247
  function test_zeroAddressDeployer_create2_reverts() public {
248
- vm.expectRevert(JBAddressRegistry.JBAddressRegistry_ZeroDeployer.selector);
248
+ vm.expectRevert(abi.encodeWithSelector(JBAddressRegistry.JBAddressRegistry_ZeroDeployer.selector, address(0)));
249
249
  registry.registerAddress(address(0), bytes32(uint256(42)), hex"60006000f3");
250
250
  }
251
251
 
@@ -28,7 +28,7 @@ contract DeploymentHelperNonceSideEffectTest is Test {
28
28
  vm.etch(registry, hex"6080604052");
29
29
 
30
30
  string memory json = string.concat('{"address":"', vm.toString(registry), '"}');
31
- string memory dir = "test/audit/tmp-nonce/nana-address-registry-v6/anvil/";
31
+ string memory dir = "test/regression/tmp-nonce/nana-address-registry-v6/anvil/";
32
32
  string memory file = string.concat(dir, "JBAddressRegistry.json");
33
33
 
34
34
  vm.createDir(dir, true);
@@ -36,7 +36,7 @@ contract DeploymentHelperNonceSideEffectTest is Test {
36
36
 
37
37
  uint64 nonceBefore = vm.getNonce(address(caller));
38
38
 
39
- caller.getDeployment("test/audit/tmp-nonce/");
39
+ caller.getDeployment("test/regression/tmp-nonce/");
40
40
 
41
41
  uint64 nonceAfter = vm.getNonce(address(caller));
42
42
 
@@ -16,13 +16,14 @@ contract DeploymentLibCaller {
16
16
  string memory networkName
17
17
  )
18
18
  external
19
+ view
19
20
  returns (AddressRegistryDeployment memory)
20
21
  {
21
22
  return AddressRegistryDeploymentLib.getDeployment({path: path, networkName: networkName});
22
23
  }
23
24
  }
24
25
 
25
- /// @notice Tests M-40: Deployment helper rejects stale artifacts pointing to non-contract addresses.
26
+ /// @notice Tests Deployment helper rejects stale artifacts pointing to non-contract addresses.
26
27
  contract DeploymentHelperValidationTest is Test {
27
28
  DeploymentLibCaller internal caller;
28
29
 
@@ -35,12 +36,12 @@ contract DeploymentHelperValidationTest is Test {
35
36
  address eoa = makeAddr("staleEOA");
36
37
  string memory json = string.concat('{"address":"', vm.toString(eoa), '"}');
37
38
 
38
- string memory dir = "test/audit/tmp-eoa/nana-address-registry-v6/testnet/";
39
+ string memory dir = "test/regression/tmp-eoa/nana-address-registry-v6/testnet/";
39
40
  vm.createDir(dir, true);
40
41
  vm.writeFile(string.concat(dir, "JBAddressRegistry.json"), json);
41
42
 
42
43
  vm.expectRevert("AddressRegistryDeploymentLib: registry has no code");
43
- caller.getDeployment({path: "test/audit/tmp-eoa/", networkName: "testnet"});
44
+ caller.getDeployment({path: "test/regression/tmp-eoa/", networkName: "testnet"});
44
45
 
45
46
  vm.removeFile(string.concat(dir, "JBAddressRegistry.json"));
46
47
  }
@@ -51,11 +52,11 @@ contract DeploymentHelperValidationTest is Test {
51
52
  vm.etch(registry, hex"6080604052");
52
53
  string memory json = string.concat('{"address":"', vm.toString(registry), '"}');
53
54
 
54
- string memory dir = "test/audit/tmp-contract/nana-address-registry-v6/testnet/";
55
+ string memory dir = "test/regression/tmp-contract/nana-address-registry-v6/testnet/";
55
56
  vm.createDir(dir, true);
56
57
  vm.writeFile(string.concat(dir, "JBAddressRegistry.json"), json);
57
58
 
58
- caller.getDeployment({path: "test/audit/tmp-contract/", networkName: "testnet"});
59
+ caller.getDeployment({path: "test/regression/tmp-contract/", networkName: "testnet"});
59
60
 
60
61
  vm.removeFile(string.concat(dir, "JBAddressRegistry.json"));
61
62
  }
@@ -5,7 +5,7 @@ import {Test} from "forge-std/Test.sol";
5
5
 
6
6
  import {JBAddressRegistry} from "../../src/JBAddressRegistry.sol";
7
7
 
8
- contract CodexFrontRunRegistrationDoSTest is Test {
8
+ contract RegressionFrontRunRegistrationDoSTest is Test {
9
9
  JBAddressRegistry internal registry;
10
10
  MockPostDeployRegistrar internal deployer;
11
11
 
@@ -5,7 +5,7 @@ import {Test} from "forge-std/Test.sol";
5
5
 
6
6
  import {JBAddressRegistry} from "../../src/JBAddressRegistry.sol";
7
7
 
8
- contract CodexUnauthorizedRegistrarTest is Test {
8
+ contract RegressionUnauthorizedRegistrarTest is Test {
9
9
  JBAddressRegistry internal registry;
10
10
  address internal deployer = makeAddr("deployer");
11
11
  address internal attacker = makeAddr("attacker");
@@ -16,7 +16,7 @@ contract ZeroDeployerRegistrationTest is Test {
16
16
  function test_createRegistrationWithZeroDeployerReverts() external {
17
17
  uint256 nonce = 1;
18
18
 
19
- vm.expectRevert(JBAddressRegistry.JBAddressRegistry_ZeroDeployer.selector);
19
+ vm.expectRevert(abi.encodeWithSelector(JBAddressRegistry.JBAddressRegistry_ZeroDeployer.selector, address(0)));
20
20
  registry.registerAddress(address(0), nonce);
21
21
  }
22
22
 
@@ -25,7 +25,7 @@ contract ZeroDeployerRegistrationTest is Test {
25
25
  bytes32 salt = keccak256("salt");
26
26
  bytes memory bytecode = hex"60006000f3";
27
27
 
28
- vm.expectRevert(JBAddressRegistry.JBAddressRegistry_ZeroDeployer.selector);
28
+ vm.expectRevert(abi.encodeWithSelector(JBAddressRegistry.JBAddressRegistry_ZeroDeployer.selector, address(0)));
29
29
  registry.registerAddress(address(0), salt, bytecode);
30
30
  }
31
31
  }
@@ -1,10 +0,0 @@
1
- {
2
- "detectors_to_exclude": "timestamp,uninitialized-local,naming-convention,solc-version,shadowing-local",
3
- "exclude_informational": true,
4
- "exclude_low": false,
5
- "exclude_medium": false,
6
- "exclude_high": false,
7
- "disable_color": false,
8
- "filter_paths": "(mocks/|test/|node_modules/|lib/)",
9
- "legacy_ast": false
10
- }