@bananapus/address-registry-v6 0.0.20 → 0.0.24

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.
@@ -8,7 +8,7 @@ Find issues that:
8
8
 
9
9
  - let callers register contracts under the wrong deployer
10
10
  - break determinism or uniqueness assumptions around registration
11
- - let a malicious deployer spoof provenance for contracts it did not create
11
+ - let callers spoof provenance for contracts the claimed deployer did not create
12
12
  - create truncation-related collisions or stale mapping assumptions
13
13
 
14
14
  ## Scope
@@ -35,8 +35,8 @@ The registry maps deployed addresses to the deployer that created them. Downstre
35
35
 
36
36
  | Role | Powers | How constrained |
37
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 |
38
+ | Registrant | Register contracts by supplying deterministic deployment inputs | Must supply inputs that reconstruct an already-deployed contract address |
39
+ | Registry reader | Interpret provenance for downstream decisions | Must pair provenance with an external trust model |
40
40
 
41
41
  ## Integration Assumptions
42
42
 
@@ -47,7 +47,7 @@ The registry maps deployed addresses to the deployer that created them. Downstre
47
47
  ## Critical Invariants
48
48
 
49
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.
50
+ Only inputs matching the actual deployer path may create a successful registration for a contract.
51
51
  2. One contract maps to one authoritative deployer record.
52
52
  No aliasing or overwrite path should let a later caller replace provenance unexpectedly.
53
53
  3. Registration metadata is stable.
package/STYLE_GUIDE.md CHANGED
@@ -419,7 +419,7 @@ jobs:
419
419
  submodules: recursive
420
420
  - uses: actions/setup-node@v4
421
421
  with:
422
- node-version: 22.4.x
422
+ node-version: 25.9.0
423
423
  - name: Install npm dependencies
424
424
  run: npm install --omit=dev
425
425
  - name: Install Foundry
@@ -470,13 +470,13 @@ jobs:
470
470
  submodules: recursive
471
471
  - uses: actions/setup-node@v4
472
472
  with:
473
- node-version: latest
473
+ node-version: 25.9.0
474
474
  - name: Install npm dependencies
475
475
  run: npm install --omit=dev
476
476
  - name: Install Foundry
477
477
  uses: foundry-rs/foundry-toolchain@v1
478
478
  - name: Run slither
479
- uses: crytic/slither-action@v0.3.1
479
+ uses: crytic/slither-action@v0.4.1
480
480
  with:
481
481
  slither-config: slither-ci.config.json
482
482
  fail-on: medium
@@ -515,7 +515,7 @@ jobs:
515
515
  },
516
516
  "dependencies": { ... },
517
517
  "devDependencies": {
518
- "@sphinx-labs/plugins": "^0.33.2"
518
+ "@sphinx-labs/plugins": "0.33.3"
519
519
  }
520
520
  }
521
521
  ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bananapus/address-registry-v6",
3
- "version": "0.0.20",
3
+ "version": "0.0.24",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
@@ -18,9 +18,9 @@
18
18
  "artifacts": "source ./.env && npx sphinx artifacts --org-id 'ea165b21-7cdc-4d7b-be59-ecdd4c26bee4' --project-name 'nana-address-registry-v6'"
19
19
  },
20
20
  "dependencies": {
21
- "@openzeppelin/contracts": "^5.6.1"
21
+ "@sphinx-labs/contracts": "0.23.1"
22
22
  },
23
23
  "devDependencies": {
24
- "@sphinx-labs/plugins": "^0.33.2"
24
+ "@sphinx-labs/plugins": "0.33.3"
25
25
  }
26
26
  }
@@ -4,7 +4,7 @@ pragma solidity 0.8.28;
4
4
  import {Sphinx} from "@sphinx-labs/contracts/contracts/foundry/SphinxPlugin.sol";
5
5
  import {Script} from "forge-std/Script.sol";
6
6
 
7
- import {JBAddressRegistry} from "src/JBAddressRegistry.sol";
7
+ import {JBAddressRegistry} from "../src/JBAddressRegistry.sol";
8
8
 
9
9
  contract Deploy is Script, Sphinx {
10
10
  bytes32 constant ADDRESS_REGISTRY_SALT = "_JBAddressRegistryV6_";
@@ -72,6 +72,26 @@ contract JBAddressRegistry is IJBAddressRegistry {
72
72
  _registerAddress({addr: hook, deployer: deployer});
73
73
  }
74
74
 
75
+ //*********************************************************************//
76
+ // ------------------------ internal functions ----------------------- //
77
+ //*********************************************************************//
78
+
79
+ /// @notice Register a contract's deployer in the `deployerOf` mapping.
80
+ /// @param addr The deployed contract's address.
81
+ /// @param deployer The deployer's address.
82
+ function _registerAddress(address addr, address deployer) internal {
83
+ // The registry only records non-zero deployers.
84
+ if (deployer == address(0)) revert JBAddressRegistry_ZeroDeployer();
85
+ // The address must already contain runtime code before it can be registered.
86
+ if (addr.code.length == 0) revert JBAddressRegistry_AddressNotDeployed(addr);
87
+ // Each address can only be registered once.
88
+ if (deployerOf[addr] != address(0)) revert JBAddressRegistry_AlreadyRegistered(addr);
89
+
90
+ deployerOf[addr] = deployer;
91
+
92
+ emit AddressRegistered({addr: addr, deployer: deployer, caller: msg.sender});
93
+ }
94
+
75
95
  //*********************************************************************//
76
96
  // -------------------------- internal views ------------------------- //
77
97
  //*********************************************************************//
@@ -126,24 +146,4 @@ contract JBAddressRegistry is IJBAddressRegistry {
126
146
  addr := mload(0)
127
147
  }
128
148
  }
129
-
130
- //*********************************************************************//
131
- // ------------------------ internal functions ----------------------- //
132
- //*********************************************************************//
133
-
134
- /// @notice Register a contract's deployer in the `deployerOf` mapping.
135
- /// @param addr The deployed contract's address.
136
- /// @param deployer The deployer's address.
137
- function _registerAddress(address addr, address deployer) internal {
138
- // The registry only records non-zero deployers.
139
- if (deployer == address(0)) revert JBAddressRegistry_ZeroDeployer();
140
- // The address must already contain runtime code before it can be registered.
141
- if (addr.code.length == 0) revert JBAddressRegistry_AddressNotDeployed(addr);
142
- // Each address can only be registered once.
143
- if (deployerOf[addr] != address(0)) revert JBAddressRegistry_AlreadyRegistered(addr);
144
-
145
- deployerOf[addr] = deployer;
146
-
147
- emit AddressRegistered({addr: addr, deployer: deployer, caller: msg.sender});
148
- }
149
149
  }
@@ -3,7 +3,7 @@ pragma solidity 0.8.28;
3
3
 
4
4
  import {Test} from "forge-std/Test.sol";
5
5
 
6
- import {JBAddressRegistry} from "src/JBAddressRegistry.sol";
6
+ import {JBAddressRegistry} from "../../src/JBAddressRegistry.sol";
7
7
 
8
8
  contract CodexFrontRunRegistrationDoSTest is Test {
9
9
  JBAddressRegistry internal registry;
@@ -0,0 +1,59 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity 0.8.28;
3
+
4
+ import {Test} from "forge-std/Test.sol";
5
+
6
+ import {JBAddressRegistry} from "../../src/JBAddressRegistry.sol";
7
+
8
+ contract CodexUnauthorizedRegistrarTest is Test {
9
+ JBAddressRegistry internal registry;
10
+ address internal deployer = makeAddr("deployer");
11
+ address internal attacker = makeAddr("attacker");
12
+
13
+ function setUp() public {
14
+ registry = new JBAddressRegistry();
15
+ }
16
+
17
+ function test_attackerCanFinalizeCreateRegistrationForAnotherDeployersContract() external {
18
+ uint64 nonce = 7;
19
+ vm.setNonce(deployer, nonce);
20
+
21
+ vm.prank(deployer);
22
+ address deployed = address(new MockDeployment());
23
+
24
+ vm.prank(attacker);
25
+ registry.registerAddress(deployer, nonce);
26
+
27
+ assertEq(registry.deployerOf(deployed), deployer, "attacker should be able to write the record");
28
+
29
+ vm.prank(deployer);
30
+ vm.expectRevert(
31
+ abi.encodeWithSelector(JBAddressRegistry.JBAddressRegistry_AlreadyRegistered.selector, deployed)
32
+ );
33
+ registry.registerAddress(deployer, nonce);
34
+ }
35
+
36
+ function test_attackerCanFinalizeCreate2RegistrationForAnotherDeployersContract() external {
37
+ Create2Factory factory = new Create2Factory();
38
+ bytes32 salt = keccak256("salt");
39
+ address deployed = factory.deploy(salt);
40
+
41
+ vm.prank(attacker);
42
+ registry.registerAddress(address(factory), salt, type(MockDeployment).creationCode);
43
+
44
+ assertEq(registry.deployerOf(deployed), address(factory), "attacker should be able to write the record");
45
+
46
+ vm.expectRevert(
47
+ abi.encodeWithSelector(JBAddressRegistry.JBAddressRegistry_AlreadyRegistered.selector, deployed)
48
+ );
49
+ registry.registerAddress(address(factory), salt, type(MockDeployment).creationCode);
50
+ }
51
+ }
52
+
53
+ contract Create2Factory {
54
+ function deploy(bytes32 salt) external returns (address deployed) {
55
+ deployed = address(new MockDeployment{salt: salt}());
56
+ }
57
+ }
58
+
59
+ contract MockDeployment {}
@@ -0,0 +1,47 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity 0.8.28;
3
+
4
+ import {Test} from "forge-std/Test.sol";
5
+
6
+ import {
7
+ AddressRegistryDeploymentLib,
8
+ AddressRegistryDeployment
9
+ } from "../../script/helpers/AddressRegistryDeploymentLib.sol";
10
+
11
+ /// @notice Wrapper that exposes the library's chain-aware overload.
12
+ contract DeploymentLibAutoCaller {
13
+ function getDeployment(string memory path) external returns (AddressRegistryDeployment memory) {
14
+ return AddressRegistryDeploymentLib.getDeployment(path);
15
+ }
16
+ }
17
+
18
+ /// @notice Verifies that auto-discovering the network name has an on-chain side effect.
19
+ contract DeploymentHelperNonceSideEffectTest is Test {
20
+ DeploymentLibAutoCaller internal caller;
21
+
22
+ function setUp() public {
23
+ caller = new DeploymentLibAutoCaller();
24
+ }
25
+
26
+ function test_getDeployment_pathOverloadConsumesCallersCreateNonce() external {
27
+ address registry = makeAddr("registryContract");
28
+ vm.etch(registry, hex"6080604052");
29
+
30
+ string memory json = string.concat('{"address":"', vm.toString(registry), '"}');
31
+ string memory dir = "test/audit/tmp-nonce/nana-address-registry-v6/anvil/";
32
+ string memory file = string.concat(dir, "JBAddressRegistry.json");
33
+
34
+ vm.createDir(dir, true);
35
+ vm.writeFile(file, json);
36
+
37
+ uint64 nonceBefore = vm.getNonce(address(caller));
38
+
39
+ caller.getDeployment("test/audit/tmp-nonce/");
40
+
41
+ uint64 nonceAfter = vm.getNonce(address(caller));
42
+
43
+ assertEq(nonceAfter, nonceBefore + 1, "library should deploy SphinxConstants and consume one CREATE nonce");
44
+
45
+ vm.removeFile(file);
46
+ }
47
+ }
@@ -3,7 +3,7 @@ pragma solidity 0.8.28;
3
3
 
4
4
  import {Test} from "forge-std/Test.sol";
5
5
 
6
- import {JBAddressRegistry} from "src/JBAddressRegistry.sol";
6
+ import {JBAddressRegistry} from "../../src/JBAddressRegistry.sol";
7
7
 
8
8
  contract ZeroDeployerRegistrationTest is Test {
9
9
  JBAddressRegistry internal registry;