@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.
- package/AUDIT_INSTRUCTIONS.md +4 -4
- package/STYLE_GUIDE.md +4 -4
- package/package.json +3 -3
- package/script/Deploy.s.sol +1 -1
- package/src/JBAddressRegistry.sol +38 -39
- package/src/interfaces/IJBAddressRegistry.sol +14 -13
- package/test/audit/CodexFrontRunRegistrationDoS.t.sol +1 -1
- package/test/audit/CodexUnauthorizedRegistrar.t.sol +1 -1
- package/test/audit/ZeroDeployerRegistration.t.sol +1 -1
package/AUDIT_INSTRUCTIONS.md
CHANGED
|
@@ -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
|
|
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
|
-
|
|
|
39
|
-
| Registry reader |
|
|
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
|
|
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:
|
|
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:
|
|
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.
|
|
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": "
|
|
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.
|
|
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
|
-
"@
|
|
21
|
+
"@sphinx-labs/contracts": "0.23.1"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
|
-
"@sphinx-labs/plugins": "
|
|
24
|
+
"@sphinx-labs/plugins": "0.33.3"
|
|
25
25
|
}
|
|
26
26
|
}
|
package/script/Deploy.s.sol
CHANGED
|
@@ -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
|
|
7
|
-
///
|
|
8
|
-
///
|
|
9
|
-
///
|
|
10
|
-
///
|
|
11
|
-
///
|
|
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
|
|
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
|
|
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
|
|
47
|
-
///
|
|
48
|
-
/// @param deployer The address
|
|
49
|
-
/// @param nonce The
|
|
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
|
|
59
|
-
///
|
|
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
|
|
64
|
-
/// @param salt The `create2` salt used
|
|
65
|
-
/// @param bytecode The
|
|
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
|
|
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
|
|
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
|
|
13
|
-
/// @param addr The address of the contract to
|
|
14
|
-
/// @return deployer The
|
|
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
|
|
19
|
-
/// @param nonce The
|
|
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
|
|
24
|
-
/// @param salt The `create2` salt used
|
|
25
|
-
/// @param bytecode The
|
|
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;
|