@bananapus/address-registry-v6 0.0.21 → 0.0.25

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.21",
3
+ "version": "0.0.25",
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_";
@@ -3,14 +3,12 @@ pragma solidity 0.8.28;
3
3
 
4
4
  import {IJBAddressRegistry} from "./interfaces/IJBAddressRegistry.sol";
5
5
 
6
- /// @notice Frontend clients need a way to verify that a Juicebox contract has a deployer they trust.
7
- /// `JBAddressRegistry` allows any contract deployed with `create` or `create2` to publicly register its deployer's
8
- /// address. Whoever deploys
9
- /// a contract is responsible for registering it.
10
- /// @dev `JBAddressRegistry` is intended for registering the deployers of Juicebox pay/redeem hooks, but does not
11
- /// enforce adherence to an interface, and can be used for any `create`/`create2` deployer.
12
- /// @dev The addresses of the deployed contracts are computed deterministically based on the deployer's address, and a
13
- /// nonce (for `create`) or `create2` salt and deployment bytecode (for `create2`).
6
+ /// @notice A public registry that records who deployed a given contract. Anyone can register a contract's deployer,
7
+ /// and anyone can look it up enabling frontend clients and other contracts to verify that a Juicebox hook or
8
+ /// extension was deployed by a trusted source.
9
+ /// @dev Supports both `create` (deployer + nonce) and `create2` (deployer + salt + bytecode) deployments. The
10
+ /// registry computes the expected contract address deterministically and verifies that code exists there before
11
+ /// recording the deployer. Each address can only be registered once.
14
12
  contract JBAddressRegistry is IJBAddressRegistry {
15
13
  //*********************************************************************//
16
14
  // --------------------------- custom errors ------------------------- //
@@ -34,19 +32,20 @@ contract JBAddressRegistry is IJBAddressRegistry {
34
32
  // --------------------- public stored properties -------------------- //
35
33
  //*********************************************************************//
36
34
 
37
- /// @notice Returns the deployer of a given contract which has been registered.
35
+ /// @notice Look up who deployed a registered contract. Returns `address(0)` if the contract hasn't been
36
+ /// registered.
38
37
  /// @dev Whoever deploys a contract is responsible for registering it.
39
- /// @custom:param addr The address of the contract to get the deployer of.
38
+ /// @custom:param addr The address of the contract to check.
40
39
  mapping(address addr => address deployer) public override deployerOf;
41
40
 
42
41
  //*********************************************************************//
43
42
  // ---------------------- external transactions ---------------------- //
44
43
  //*********************************************************************//
45
44
 
46
- /// @notice Register a deployed contract's address.
47
- /// @dev The contract must be deployed using `create`.
48
- /// @param deployer The address of the contract's deployer.
49
- /// @param nonce The nonce used to deploy the contract.
45
+ /// @notice Register a contract that was deployed with `create` (standard deployment). The registry computes the
46
+ /// expected address from the deployer and nonce, then verifies code exists there.
47
+ /// @param deployer The address that deployed the contract.
48
+ /// @param nonce The deployer's transaction nonce at the time of deployment.
50
49
  function registerAddress(address deployer, uint256 nonce) external override {
51
50
  // Calculate the address of the contract, assuming it was deployed using `create` with the specified nonce.
52
51
  address hook = _addressFrom({origin: deployer, nonce: nonce});
@@ -55,14 +54,14 @@ contract JBAddressRegistry is IJBAddressRegistry {
55
54
  _registerAddress({addr: hook, deployer: deployer});
56
55
  }
57
56
 
58
- /// @notice Register a deployed contract's address.
59
- /// @dev The contract must be deployed using `create2`.
57
+ /// @notice Register a contract that was deployed with `create2` (deterministic deployment). The registry computes
58
+ /// the expected address from the deployer, salt, and bytecode, then verifies code exists there.
60
59
  /// @dev The `create2` salt is determined by the deployer's logic. The deployment bytecode can be retrieved offchain
61
60
  /// (from the deployment transaction) or onchain (with `abi.encodePacked(type(deployedContract).creationCode,
62
61
  /// abi.encode(constructorArguments))`).
63
- /// @param deployer The address of the contract's deployer.
64
- /// @param salt The `create2` salt used to deploy the contract.
65
- /// @param bytecode The contract's deployment bytecode, including the constructor arguments.
62
+ /// @param deployer The address that deployed the contract.
63
+ /// @param salt The `create2` salt used during deployment.
64
+ /// @param bytecode The full deployment bytecode, including constructor arguments.
66
65
  function registerAddress(address deployer, bytes32 salt, bytes calldata bytecode) external override {
67
66
  // Calculate the address of the contract using the provided `create2` salt and deployment bytecode.
68
67
  address hook =
@@ -72,6 +71,26 @@ contract JBAddressRegistry is IJBAddressRegistry {
72
71
  _registerAddress({addr: hook, deployer: deployer});
73
72
  }
74
73
 
74
+ //*********************************************************************//
75
+ // ------------------------ internal functions ----------------------- //
76
+ //*********************************************************************//
77
+
78
+ /// @notice Register a contract's deployer in the `deployerOf` mapping.
79
+ /// @param addr The deployed contract's address.
80
+ /// @param deployer The deployer's address.
81
+ function _registerAddress(address addr, address deployer) internal {
82
+ // The registry only records non-zero deployers.
83
+ if (deployer == address(0)) revert JBAddressRegistry_ZeroDeployer();
84
+ // The address must already contain runtime code before it can be registered.
85
+ if (addr.code.length == 0) revert JBAddressRegistry_AddressNotDeployed(addr);
86
+ // Each address can only be registered once.
87
+ if (deployerOf[addr] != address(0)) revert JBAddressRegistry_AlreadyRegistered(addr);
88
+
89
+ deployerOf[addr] = deployer;
90
+
91
+ emit AddressRegistered({addr: addr, deployer: deployer, caller: msg.sender});
92
+ }
93
+
75
94
  //*********************************************************************//
76
95
  // -------------------------- internal views ------------------------- //
77
96
  //*********************************************************************//
@@ -126,24 +145,4 @@ contract JBAddressRegistry is IJBAddressRegistry {
126
145
  addr := mload(0)
127
146
  }
128
147
  }
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
148
  }
@@ -1,27 +1,28 @@
1
1
  // SPDX-License-Identifier: MIT
2
2
  pragma solidity ^0.8.0;
3
3
 
4
- /// @notice A registry that maps deployed contract addresses to their deployers.
4
+ /// @notice A registry that maps deployed contract addresses to their deployers, allowing anyone to verify who deployed
5
+ /// a given contract. Primarily used to verify the trustworthiness of Juicebox hooks and extensions.
5
6
  interface IJBAddressRegistry {
6
- /// @notice Emitted when a contract address is registered.
7
+ /// @notice Emitted when a contract's deployer is registered.
7
8
  /// @param addr The address of the registered contract.
8
- /// @param deployer The address of the contract's deployer.
9
+ /// @param deployer The address that deployed the contract.
9
10
  /// @param caller The address that called the register function.
10
11
  event AddressRegistered(address indexed addr, address indexed deployer, address caller);
11
12
 
12
- /// @notice Returns the deployer of a given contract which has been registered.
13
- /// @param addr The address of the contract to get the deployer of.
14
- /// @return deployer The deployer of the contract.
13
+ /// @notice Look up who deployed a registered contract.
14
+ /// @param addr The address of the contract to check.
15
+ /// @return deployer The address that deployed the contract, or `address(0)` if not registered.
15
16
  function deployerOf(address addr) external view returns (address deployer);
16
17
 
17
- /// @notice Register a contract deployed with `create`.
18
- /// @param deployer The address of the contract's deployer.
19
- /// @param nonce The nonce used to deploy the contract.
18
+ /// @notice Register a contract that was deployed with `create` (standard deployment).
19
+ /// @param deployer The address that deployed the contract.
20
+ /// @param nonce The deployer's transaction nonce at the time of deployment.
20
21
  function registerAddress(address deployer, uint256 nonce) external;
21
22
 
22
- /// @notice Register a contract deployed with `create2`.
23
- /// @param deployer The address of the contract's deployer.
24
- /// @param salt The `create2` salt used to deploy the contract.
25
- /// @param bytecode The contract's deployment bytecode, including the constructor arguments.
23
+ /// @notice Register a contract that was deployed with `create2` (deterministic deployment).
24
+ /// @param deployer The address that deployed the contract.
25
+ /// @param salt The `create2` salt used during deployment.
26
+ /// @param bytecode The full deployment bytecode, including constructor arguments.
26
27
  function registerAddress(address deployer, bytes32 salt, bytes calldata bytecode) external;
27
28
  }
@@ -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;
@@ -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 CodexUnauthorizedRegistrarTest is Test {
9
9
  JBAddressRegistry internal registry;
@@ -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;