@bananapus/address-registry-v6 0.0.9 → 0.0.11
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 +122 -0
- package/CHANGE_LOG.md +88 -0
- package/README.md +1 -1
- package/RISKS.md +12 -14
- package/USER_JOURNEYS.md +144 -0
- package/package.json +1 -1
- package/script/helpers/AddressRegistryDeploymentLib.sol +1 -1
- package/deployments/nana-address-registry/arbitrum/JBAddressRegistry.json +0 -177
- package/deployments/nana-address-registry/arbitrum_sepolia/JBAddressRegistry.json +0 -177
- package/deployments/nana-address-registry/base/JBAddressRegistry.json +0 -181
- package/deployments/nana-address-registry/base_sepolia/JBAddressRegistry.json +0 -181
- package/deployments/nana-address-registry/ethereum/JBAddressRegistry.json +0 -181
- package/deployments/nana-address-registry/optimism/JBAddressRegistry.json +0 -177
- package/deployments/nana-address-registry/optimism_sepolia/JBAddressRegistry.json +0 -181
- package/deployments/nana-address-registry/sepolia/JBAddressRegistry.json +0 -181
- package/docs/book.css +0 -13
- package/docs/book.toml +0 -12
- package/docs/solidity.min.js +0 -74
- package/docs/src/README.md +0 -164
- package/docs/src/SUMMARY.md +0 -6
- package/docs/src/src/JBAddressRegistry.sol/contract.JBAddressRegistry.md +0 -106
- package/docs/src/src/README.md +0 -5
- package/docs/src/src/interfaces/IJBAddressRegistry.sol/interface.IJBAddressRegistry.md +0 -33
- package/docs/src/src/interfaces/README.md +0 -4
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
# Audit Instructions -- nana-address-registry-v6
|
|
2
|
+
|
|
3
|
+
You are auditing a permissionless address registry for Juicebox V6. The contract stores a mapping from deployed contract addresses to their deployers, computed deterministically from `create` or `create2` parameters. It has no owner, no access control, no constructor arguments, and no external dependencies. Read [RISKS.md](./RISKS.md) first -- it documents all known risks and trust assumptions. Then come back here.
|
|
4
|
+
|
|
5
|
+
## Scope
|
|
6
|
+
|
|
7
|
+
**In scope -- all Solidity in `src/`:**
|
|
8
|
+
```
|
|
9
|
+
src/JBAddressRegistry.sol # Registry implementation (~127 lines)
|
|
10
|
+
src/interfaces/IJBAddressRegistry.sol # Interface (~27 lines)
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
**Out of scope:** Test files, deployment scripts, forge-std.
|
|
14
|
+
|
|
15
|
+
## Architecture
|
|
16
|
+
|
|
17
|
+
### JBAddressRegistry
|
|
18
|
+
|
|
19
|
+
A standalone, stateless-logic contract with a single storage mapping:
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
mapping(address addr => address deployer) public deployerOf;
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Two public `registerAddress` overloads accept deployer parameters, compute the deterministic address, and store the mapping. No validation is performed beyond address computation and a nonce range check.
|
|
26
|
+
|
|
27
|
+
### Registration (create)
|
|
28
|
+
|
|
29
|
+
`registerAddress(address deployer, uint256 nonce)`:
|
|
30
|
+
1. Calls `_addressFrom(deployer, nonce)` to compute the `create` address via RLP encoding
|
|
31
|
+
2. Stores `deployerOf[computedAddress] = deployer`
|
|
32
|
+
3. Emits `AddressRegistered(computedAddress, deployer, msg.sender)`
|
|
33
|
+
|
|
34
|
+
### Registration (create2)
|
|
35
|
+
|
|
36
|
+
`registerAddress(address deployer, bytes32 salt, bytes calldata bytecode)`:
|
|
37
|
+
1. Computes `address(uint160(uint256(keccak256(abi.encodePacked(bytes1(0xff), deployer, salt, keccak256(bytecode))))))`
|
|
38
|
+
2. Stores `deployerOf[computedAddress] = deployer`
|
|
39
|
+
3. Emits `AddressRegistered(computedAddress, deployer, msg.sender)`
|
|
40
|
+
|
|
41
|
+
### RLP Encoding (_addressFrom)
|
|
42
|
+
|
|
43
|
+
The internal `_addressFrom(address origin, uint256 nonce)` function implements RLP encoding of `[origin, nonce]` for `create` address computation. It handles 10 nonce ranges covering `0` through `type(uint64).max`:
|
|
44
|
+
|
|
45
|
+
| Nonce Range | RLP Prefix Byte | Nonce Length Prefix |
|
|
46
|
+
|-------------|----------------|---------------------|
|
|
47
|
+
| `0` | `0xd6` | `0x80` (empty byte) |
|
|
48
|
+
| `1 - 0x7f` | `0xd6` | (none, raw byte) |
|
|
49
|
+
| `0x80 - 0xff` | `0xd7` | `0x81` |
|
|
50
|
+
| `0x100 - 0xffff` | `0xd8` | `0x82` |
|
|
51
|
+
| `0x10000 - 0xffffff` | `0xd9` | `0x83` |
|
|
52
|
+
| `0x1000000 - 0xffffffff` | `0xda` | `0x84` |
|
|
53
|
+
| `0x100000000 - 0xffffffffff` | `0xdb` | `0x85` |
|
|
54
|
+
| `0x10000000000 - 0xffffffffffff` | `0xdc` | `0x86` |
|
|
55
|
+
| `0x1000000000000 - 0xffffffffffffff` | `0xdd` | `0x87` |
|
|
56
|
+
| `0x100000000000000 - 0xffffffffffffffff` | `0xde` | `0x88` |
|
|
57
|
+
|
|
58
|
+
The final address is extracted from `keccak256(rlp_data)` via inline assembly: `mstore(0, hash); addr := mload(0)`.
|
|
59
|
+
|
|
60
|
+
Nonces above `type(uint64).max` revert with `JBAddressRegistry_NonceTooLarge`.
|
|
61
|
+
|
|
62
|
+
## Priority Audit Areas
|
|
63
|
+
|
|
64
|
+
### 1. RLP Encoding Correctness (Highest Priority)
|
|
65
|
+
|
|
66
|
+
The `_addressFrom` function is the only non-trivial logic in the contract. Verify:
|
|
67
|
+
|
|
68
|
+
- **Every nonce range boundary is correct.** The if/else chain must produce correct RLP for every boundary value: `0`, `1`, `0x7f`, `0x80`, `0xff`, `0x100`, `0xffff`, `0x10000`, etc., up to `type(uint64).max`. An off-by-one at any boundary would silently produce wrong addresses.
|
|
69
|
+
- **RLP prefix bytes are correct.** The first byte (`0xd6`-`0xde`) encodes the total length of the list. Verify each prefix matches the actual encoded data length (20-byte address + nonce encoding + overhead).
|
|
70
|
+
- **Nonce encoding is correct.** For nonce `0`, the RLP encoding is `0x80` (empty byte string), not `0x00`. For nonces `1-0x7f`, the nonce IS the RLP encoding (single byte). For `0x80+`, a length prefix is prepended.
|
|
71
|
+
- **Assembly address extraction.** The final `mstore(0, hash); addr := mload(0)` extracts the low 160 bits of the keccak256 hash. Verify this is equivalent to `address(uint160(uint256(hash)))`.
|
|
72
|
+
- **Comparison with reference implementations.** Cross-check against the Ethereum Yellow Paper, OpenZeppelin's `Create2` library, and the linked StackExchange reference (https://ethereum.stackexchange.com/a/87840/68134).
|
|
73
|
+
|
|
74
|
+
### 2. create2 Address Computation
|
|
75
|
+
|
|
76
|
+
The `create2` overload uses `abi.encodePacked(bytes1(0xff), deployer, salt, keccak256(bytecode))`. Verify:
|
|
77
|
+
- This matches the EIP-1014 specification exactly.
|
|
78
|
+
- The `bytes calldata bytecode` parameter is hashed correctly (constructor arguments must be included by the caller; the contract does not append them).
|
|
79
|
+
- No length ambiguity in the packed encoding (each component has fixed size: 1 + 20 + 32 + 32 = 85 bytes).
|
|
80
|
+
|
|
81
|
+
### 3. Overwrite Behavior
|
|
82
|
+
|
|
83
|
+
`_registerAddress` unconditionally overwrites `deployerOf[addr]`. Verify:
|
|
84
|
+
- A re-registration with the same parameters produces the same result (idempotent).
|
|
85
|
+
- A re-registration with different parameters that happen to compute the same address (collision) would overwrite. Since address collisions require a keccak256 collision, this is cryptographically infeasible -- but confirm there is no cheaper attack vector.
|
|
86
|
+
- The `caller` field in the `AddressRegistered` event correctly reflects `msg.sender`, not the `deployer` parameter.
|
|
87
|
+
|
|
88
|
+
### 4. Gas and DoS
|
|
89
|
+
|
|
90
|
+
The contract has no loops, no arrays, and no unbounded storage growth beyond the mapping. Verify:
|
|
91
|
+
- `registerAddress` has bounded gas cost regardless of inputs.
|
|
92
|
+
- The `bytecode` parameter in the `create2` overload is hashed in memory. For very large bytecode, this could consume significant memory gas but cannot cause an OOG in the registry itself (the caller pays).
|
|
93
|
+
|
|
94
|
+
## Invariants to Verify
|
|
95
|
+
|
|
96
|
+
1. **Determinism**: For any `(deployer, nonce)` pair, `_addressFrom` always returns the same address, and that address matches what the EVM would produce for a `create` deployment from `deployer` at `nonce`.
|
|
97
|
+
2. **create2 correctness**: For any `(deployer, salt, bytecode)` triple, the computed address matches what the EVM would produce for a `create2` deployment.
|
|
98
|
+
3. **No side effects**: `registerAddress` only modifies `deployerOf[computedAddress]` and emits one event. No other state is touched.
|
|
99
|
+
4. **Nonce boundary completeness**: Every valid nonce (0 through `type(uint64).max`) produces a correct RLP encoding. No nonce in this range falls through without being encoded.
|
|
100
|
+
|
|
101
|
+
## Testing Setup
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
cd nana-address-registry-v6
|
|
105
|
+
npm install
|
|
106
|
+
forge build
|
|
107
|
+
forge test
|
|
108
|
+
|
|
109
|
+
# Run edge case tests
|
|
110
|
+
forge test --match-contract JBAddressRegistryEdge -vvv
|
|
111
|
+
|
|
112
|
+
# Run nonce truncation regression test
|
|
113
|
+
forge test --match-path test/regression/NonceTruncation.t.sol -vvv
|
|
114
|
+
|
|
115
|
+
# Run fork tests
|
|
116
|
+
forge test --match-contract Fork -vvv
|
|
117
|
+
|
|
118
|
+
# Write a PoC
|
|
119
|
+
forge test --match-path test/audit/ExploitPoC.t.sol -vvv
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Go break it.
|
package/CHANGE_LOG.md
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# nana-address-registry-v6 Changelog (v5 → v6)
|
|
2
|
+
|
|
3
|
+
This document describes all changes between `nana-address-registry` (v5) and `nana-address-registry-v6` (v6).
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1. Breaking Changes
|
|
8
|
+
|
|
9
|
+
- **Solidity version bump**: `0.8.23` → `0.8.26`. Contracts compiled against v5 ABIs will still be compatible (no ABI-level breaking changes), but the compiler version requirement has changed.
|
|
10
|
+
- **Nonce range extended from `uint32` to `uint64`**: In v5, the `_addressFrom` function silently produced incorrect addresses for nonces at or above `2^32`. In v6, nonces up to `uint64.max` are correctly RLP-encoded, and nonces above `uint64.max` revert with `JBAddressRegistry_NonceTooLarge`. Any off-chain tooling that assumed the `uint32` ceiling must be updated.
|
|
11
|
+
|
|
12
|
+
## 2. New Features
|
|
13
|
+
|
|
14
|
+
- **Extended nonce support (uint40 through uint64)**: Four new RLP encoding branches handle nonces in the ranges `uint40`, `uint48`, `uint56`, and `uint64`, covering any realistic Ethereum account nonce.
|
|
15
|
+
|
|
16
|
+
## 3. Event Changes
|
|
17
|
+
|
|
18
|
+
None. The `AddressRegistered` event signature is identical between v5 and v6:
|
|
19
|
+
|
|
20
|
+
```solidity
|
|
21
|
+
event AddressRegistered(address indexed addr, address indexed deployer, address caller);
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## 4. Error Changes
|
|
25
|
+
|
|
26
|
+
| Error | v5 | v6 |
|
|
27
|
+
|---|---|---|
|
|
28
|
+
| `JBAddressRegistry_NonceTooLarge(uint256 nonce)` | Does not exist | **Added** — reverts when `nonce > type(uint64).max` |
|
|
29
|
+
|
|
30
|
+
In v5, passing a nonce larger than `uint32` fell through to the `else` branch, which cast the nonce to `uint32`, silently truncating it and producing an incorrect address. v6 replaces this silent truncation with an explicit revert.
|
|
31
|
+
|
|
32
|
+
## 5. Implementation Changes (Non-Interface)
|
|
33
|
+
|
|
34
|
+
### `_addressFrom` — RLP nonce encoding
|
|
35
|
+
|
|
36
|
+
| Aspect | v5 | v6 |
|
|
37
|
+
|---|---|---|
|
|
38
|
+
| Maximum supported nonce | `uint32` (implicit, no guard) | `uint64` (explicit revert above) |
|
|
39
|
+
| Nonce > `uint32` behavior | Silent truncation to `uint32` — incorrect address computed | Correctly encodes `uint40`–`uint64`; reverts above `uint64` |
|
|
40
|
+
| RLP branches | 6 (`0x00`, `≤0x7f`, `≤0xff`, `≤0xffff`, `≤0xffffff`, `else→uint32`) | 10 (`0x00`, `≤0x7f`, `≤0xff`, `≤0xffff`, `≤0xffffff`, `≤0xffffffff`, `≤0xffffffffff`, `≤0xffffffffffff`, `≤0xffffffffffffff`, `else→uint64`) |
|
|
41
|
+
| Lint annotations | None | `forge-lint: disable-next-line(unsafe-typecast)` on each narrowing cast; `forge-lint: disable-next-line(asm-keccak256)` on inline assembly `keccak256` |
|
|
42
|
+
|
|
43
|
+
### Internal function call style
|
|
44
|
+
|
|
45
|
+
All internal function calls now use **named arguments** for clarity:
|
|
46
|
+
|
|
47
|
+
```solidity
|
|
48
|
+
// v5
|
|
49
|
+
address hook = _addressFrom(deployer, nonce);
|
|
50
|
+
_registerAddress(hook, deployer);
|
|
51
|
+
|
|
52
|
+
// v6
|
|
53
|
+
address hook = _addressFrom({origin: deployer, nonce: nonce});
|
|
54
|
+
_registerAddress({addr: hook, deployer: deployer});
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Section header naming
|
|
58
|
+
|
|
59
|
+
| v5 | v6 |
|
|
60
|
+
|---|---|
|
|
61
|
+
| `// ---------------------- internal transactions ---------------------- //` | `// -------------------------- internal views ------------------------- //` (for `_addressFrom`) |
|
|
62
|
+
| (none) | `// ------------------------ internal functions ----------------------- //` (new section for `_registerAddress`) |
|
|
63
|
+
| (none) | `// --------------------------- custom errors ------------------------- //` (new section) |
|
|
64
|
+
|
|
65
|
+
### NatDoc comment improvements
|
|
66
|
+
|
|
67
|
+
- **Contract-level**: Fixed typo `reponsible` → `responsible`; reformatted line wrapping.
|
|
68
|
+
- **`_addressFrom`**: Replaced informal note (`"this won't work for nonces > 2**32. If you reach that nonce please: 1) ping us, because wow 2) use another deployer"`) with a precise description (`"RLP encoding of [origin, nonce]. Supports nonces up to uint64 max"`). Attribution changed from `"Taken from"` to `"Adapted from"`.
|
|
69
|
+
|
|
70
|
+
### Interface NatDoc
|
|
71
|
+
|
|
72
|
+
The v6 interface (`IJBAddressRegistry`) adds full NatDoc documentation that was absent in v5:
|
|
73
|
+
|
|
74
|
+
- `@notice` on the interface itself.
|
|
75
|
+
- `@notice`, `@param`, and `@return` tags on `AddressRegistered`, `deployerOf`, and both `registerAddress` overloads.
|
|
76
|
+
|
|
77
|
+
No function signatures, parameter types, or return types changed.
|
|
78
|
+
|
|
79
|
+
## 6. Migration Table
|
|
80
|
+
|
|
81
|
+
| v5 | v6 | Action Required |
|
|
82
|
+
|---|---|---|
|
|
83
|
+
| `IJBAddressRegistry` | `IJBAddressRegistry` | **None** — ABI-identical. Update import path only. |
|
|
84
|
+
| `JBAddressRegistry` | `JBAddressRegistry` | **None** — ABI-compatible. Deploy new instance compiled with Solidity 0.8.26. |
|
|
85
|
+
| `registerAddress(address, uint256)` | `registerAddress(address, uint256)` | **None** — signature unchanged. Nonces > `uint32` now work correctly; nonces > `uint64` now revert instead of silently producing wrong addresses. |
|
|
86
|
+
| `registerAddress(address, bytes32, bytes)` | `registerAddress(address, bytes32, bytes)` | **None** — signature unchanged. |
|
|
87
|
+
| `deployerOf(address)` | `deployerOf(address)` | **None** — signature unchanged. |
|
|
88
|
+
| (no error) | `JBAddressRegistry_NonceTooLarge(uint256)` | **New** — callers passing nonces > `uint64.max` must handle this revert. |
|
package/README.md
CHANGED
|
@@ -60,7 +60,7 @@ Deployers can be exploited or act maliciously. Clients should still communicate
|
|
|
60
60
|
|
|
61
61
|
### Limitations
|
|
62
62
|
|
|
63
|
-
- The `_addressFrom` function for `create` addresses uses RLP encoding that only supports nonces up to `
|
|
63
|
+
- The `_addressFrom` function for `create` addresses uses RLP encoding that only supports nonces up to `uint64` max (18,446,744,073,709,551,615). Higher nonces revert with `JBAddressRegistry_NonceTooLarge`. In practice, this limit is unreachable.
|
|
64
64
|
- No overwrite protection: registering the same computed address again overwrites the previous deployer. This is safe because only the correct deployer + parameters produce a given address -- a second call with the same inputs just re-registers the same deployer.
|
|
65
65
|
- Registration is permissionless -- anyone can call `registerAddress`, not just the deployer. Security relies entirely on deterministic address computation.
|
|
66
66
|
|
package/RISKS.md
CHANGED
|
@@ -1,20 +1,18 @@
|
|
|
1
|
-
# nana-address-registry-v6
|
|
1
|
+
# RISKS.md -- nana-address-registry-v6
|
|
2
2
|
|
|
3
|
-
## Trust Assumptions
|
|
3
|
+
## 1. Trust Assumptions
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
3. **Frontend Trust** — Frontends must maintain their own list of trusted deployers. The registry only provides the mapping, not a trust judgment.
|
|
5
|
+
- **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.
|
|
6
|
+
- **Frontend trust.** Frontends must maintain their own list of trusted deployers. The registry provides the mapping, not a trust judgment.
|
|
8
7
|
|
|
9
|
-
## Known Risks
|
|
8
|
+
## 2. Known Risks
|
|
10
9
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
| No unregister | Once registered, a deployer mapping cannot be removed | Intentional; provides permanent provenance |
|
|
16
|
-
| Nonce range | Supports nonces up to uint64 max | Covers any realistic Ethereum nonce |
|
|
10
|
+
- **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.
|
|
11
|
+
- **Overwrite of existing entries.** There is no check preventing re-registration. A second call with different parameters that computes the same address will overwrite the previous `deployerOf` entry.
|
|
12
|
+
- **No removal mechanism.** Once registered, an entry cannot be removed, only overwritten.
|
|
13
|
+
- **RLP encoding correctness.** The `_addressFrom` function manually implements RLP encoding for nonces up to uint64. Well-tested pattern; nonce capped at uint64 max with explicit revert.
|
|
17
14
|
|
|
18
|
-
##
|
|
15
|
+
## 3. Invariants to Verify
|
|
19
16
|
|
|
20
|
-
|
|
17
|
+
- `deployerOf[addr]` always corresponds to a valid deployer/nonce pair that produces `addr` (if registered via `registerAddress`).
|
|
18
|
+
- `create2` registrations: `deployerOf[addr]` corresponds to a valid deployer/salt/bytecodeHash that produces `addr`.
|
package/USER_JOURNEYS.md
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
# User Journeys -- nana-address-registry-v6
|
|
2
|
+
|
|
3
|
+
Concrete end-to-end flows through the address registry. Each journey traces the exact function calls, state changes, and external interactions.
|
|
4
|
+
|
|
5
|
+
## Journey 1: Register a Contract Deployed via create
|
|
6
|
+
|
|
7
|
+
**Actor:** Anyone (the deployer, the deployed contract itself, or a third party).
|
|
8
|
+
**Goal:** Record the deployer of a contract that was deployed using the `create` opcode (standard deployment).
|
|
9
|
+
|
|
10
|
+
### Precondition
|
|
11
|
+
|
|
12
|
+
A contract exists on-chain at the address that `create` would produce from `(deployer, nonce)`. The caller knows the deployer's address and the nonce used during deployment.
|
|
13
|
+
|
|
14
|
+
### Steps
|
|
15
|
+
|
|
16
|
+
1. **Caller invokes `registerAddress(address deployer, uint256 nonce)`**
|
|
17
|
+
|
|
18
|
+
- The `nonce` must be `<= type(uint64).max` or the call reverts with `JBAddressRegistry_NonceTooLarge(nonce)`
|
|
19
|
+
- The contract calls `_addressFrom(deployer, nonce)` internally
|
|
20
|
+
|
|
21
|
+
2. **`_addressFrom` computes the create address via RLP encoding**
|
|
22
|
+
|
|
23
|
+
- Selects the correct RLP encoding branch based on the nonce range (10 branches: `0`, `1-0x7f`, `0x80-0xff`, ..., up to `uint64` max)
|
|
24
|
+
- Builds the RLP-encoded byte sequence: `[list_prefix, 0x94, deployer_20_bytes, nonce_encoding]`
|
|
25
|
+
- Hashes the sequence with `keccak256`
|
|
26
|
+
- Extracts the low 160 bits as the computed address via inline assembly
|
|
27
|
+
|
|
28
|
+
3. **`_registerAddress` stores the mapping and emits the event**
|
|
29
|
+
|
|
30
|
+
- Sets `deployerOf[computedAddress] = deployer`
|
|
31
|
+
- Emits `AddressRegistered(addr: computedAddress, deployer: deployer, caller: msg.sender)`
|
|
32
|
+
|
|
33
|
+
### Result
|
|
34
|
+
|
|
35
|
+
`deployerOf[computedAddress]` now returns `deployer`. Anyone querying the registry for that address can verify who deployed it.
|
|
36
|
+
|
|
37
|
+
### What to verify
|
|
38
|
+
|
|
39
|
+
- The computed address matches the actual on-chain contract address for the given `(deployer, nonce)` pair.
|
|
40
|
+
- If the caller provides incorrect parameters (wrong nonce, wrong deployer), a mapping is still created -- but for a different (likely nonexistent) address. The registry does not verify that code exists at the computed address.
|
|
41
|
+
- Calling `registerAddress` again with the same parameters is idempotent (same result, no revert).
|
|
42
|
+
- The `caller` in the event is `msg.sender`, which may differ from `deployer`.
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## Journey 2: Register a Contract Deployed via create2
|
|
47
|
+
|
|
48
|
+
**Actor:** Anyone (the deployer, the deployed contract itself, or a third party).
|
|
49
|
+
**Goal:** Record the deployer of a contract that was deployed using the `create2` opcode (deterministic deployment).
|
|
50
|
+
|
|
51
|
+
### Precondition
|
|
52
|
+
|
|
53
|
+
A contract exists on-chain at the address that `create2` would produce from `(deployer, salt, bytecode)`. The caller knows the deployer's address, the salt, and the full creation bytecode (including constructor arguments).
|
|
54
|
+
|
|
55
|
+
### Steps
|
|
56
|
+
|
|
57
|
+
1. **Caller invokes `registerAddress(address deployer, bytes32 salt, bytes calldata bytecode)`**
|
|
58
|
+
|
|
59
|
+
- No parameter validation beyond the address computation itself
|
|
60
|
+
- `bytecode` must include ABI-encoded constructor arguments appended to the creation code
|
|
61
|
+
|
|
62
|
+
2. **The contract computes the create2 address inline**
|
|
63
|
+
|
|
64
|
+
- `address(uint160(uint256(keccak256(abi.encodePacked(bytes1(0xff), deployer, salt, keccak256(bytecode))))))`
|
|
65
|
+
- This matches the EIP-1014 specification
|
|
66
|
+
|
|
67
|
+
3. **`_registerAddress` stores the mapping and emits the event**
|
|
68
|
+
|
|
69
|
+
- Sets `deployerOf[computedAddress] = deployer`
|
|
70
|
+
- Emits `AddressRegistered(addr: computedAddress, deployer: deployer, caller: msg.sender)`
|
|
71
|
+
|
|
72
|
+
### Result
|
|
73
|
+
|
|
74
|
+
`deployerOf[computedAddress]` now returns `deployer`. Frontends and other contracts can look up the deployer of any `create2`-deployed contract.
|
|
75
|
+
|
|
76
|
+
### What to verify
|
|
77
|
+
|
|
78
|
+
- The `bytecode` parameter must be the full creation bytecode, not the deployed (runtime) bytecode. Omitting constructor arguments produces a different hash and therefore a different address.
|
|
79
|
+
- For large bytecode payloads, `keccak256(bytecode)` is computed in memory. The gas cost scales with bytecode size, but the registry itself has no gas limit issues -- the caller pays.
|
|
80
|
+
- The salt is deployer-specific. Different deployers with the same salt and bytecode produce different addresses (because the deployer address is part of the hash input).
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
## Journey 3: Frontend Verifies a Hook's Deployer
|
|
85
|
+
|
|
86
|
+
**Actor:** Frontend application or off-chain service.
|
|
87
|
+
**Goal:** Determine whether a Juicebox hook was deployed by a trusted factory.
|
|
88
|
+
|
|
89
|
+
### Precondition
|
|
90
|
+
|
|
91
|
+
The hook contract has been registered in the registry (via Journey 1 or 2). The frontend maintains a list of trusted deployer addresses.
|
|
92
|
+
|
|
93
|
+
### Steps
|
|
94
|
+
|
|
95
|
+
1. **Frontend reads `deployerOf(hookAddress)`**
|
|
96
|
+
|
|
97
|
+
- This is a simple public mapping getter -- a `staticcall` with no state changes
|
|
98
|
+
- Returns `address(0)` if the hook has never been registered
|
|
99
|
+
|
|
100
|
+
2. **Frontend evaluates the result**
|
|
101
|
+
|
|
102
|
+
- If `deployer == address(0)`: the hook is unregistered. The frontend should treat it as untrusted.
|
|
103
|
+
- If `deployer` is in the trusted deployer set: the hook was deployed by a known, audited factory. The frontend can display it with confidence.
|
|
104
|
+
- If `deployer` is a non-zero address not in the trusted set: the hook is registered but was deployed by an unknown deployer. The frontend should flag it as unverified.
|
|
105
|
+
|
|
106
|
+
### Result
|
|
107
|
+
|
|
108
|
+
The frontend can make a trust decision about the hook without needing to trace the deployment transaction on-chain.
|
|
109
|
+
|
|
110
|
+
### What to verify
|
|
111
|
+
|
|
112
|
+
- `deployerOf` returns `address(0)` for any address that has never been registered. There is no way to distinguish "never registered" from "registered with `deployer = address(0)`", though the latter requires deliberately passing `address(0)` as the deployer.
|
|
113
|
+
- The registry provides no guarantee that code exists at the registered address. A deployer could register an address for a contract that has been self-destructed or was never deployed.
|
|
114
|
+
- The registry provides no guarantee that the registered deployer is the *actual* deployer. It only guarantees that the deterministic computation of `(deployer, nonce)` or `(deployer, salt, bytecode)` produces that address. Since the EVM's address derivation is deterministic, this is equivalent -- but the registry itself does not verify the deployment transaction.
|
|
115
|
+
|
|
116
|
+
---
|
|
117
|
+
|
|
118
|
+
## Journey 4: Overwrite a Previous Registration
|
|
119
|
+
|
|
120
|
+
**Actor:** Anyone.
|
|
121
|
+
**Goal:** Re-register an address with the same or different parameters.
|
|
122
|
+
|
|
123
|
+
### Precondition
|
|
124
|
+
|
|
125
|
+
`deployerOf[addr]` already has a non-zero value from a previous registration.
|
|
126
|
+
|
|
127
|
+
### Steps
|
|
128
|
+
|
|
129
|
+
1. **Caller invokes either `registerAddress` overload with parameters that compute to `addr`**
|
|
130
|
+
|
|
131
|
+
2. **`_registerAddress` overwrites the existing value**
|
|
132
|
+
|
|
133
|
+
- `deployerOf[addr] = deployer` (unconditional write, no check for existing value)
|
|
134
|
+
- Emits a new `AddressRegistered` event
|
|
135
|
+
|
|
136
|
+
### Result
|
|
137
|
+
|
|
138
|
+
The previous deployer mapping is overwritten. The event log contains both the old and new registrations.
|
|
139
|
+
|
|
140
|
+
### What to verify
|
|
141
|
+
|
|
142
|
+
- Overwriting is safe because the same address can only be computed from the same `(deployer, nonce)` or `(deployer, salt, bytecode)` parameters (assuming no keccak256 collision). Re-registering with the same parameters produces the same result.
|
|
143
|
+
- There is no way to "unregister" an address. Setting `deployerOf[addr] = address(0)` would require computing a `(deployer, nonce)` pair that produces `addr` with `deployer = address(0)`, which is theoretically possible but practically useless.
|
|
144
|
+
- The event log preserves the full history of registrations. Off-chain indexers can detect overwrites by tracking multiple `AddressRegistered` events for the same `addr`.
|
package/package.json
CHANGED
|
@@ -47,7 +47,7 @@ library AddressRegistryDeploymentLib {
|
|
|
47
47
|
deployment.registry = IJBAddressRegistry(
|
|
48
48
|
_getDeploymentAddress({
|
|
49
49
|
path: path,
|
|
50
|
-
projectName: "nana-address-registry",
|
|
50
|
+
projectName: "nana-address-registry-v6",
|
|
51
51
|
networkName: networkName,
|
|
52
52
|
contractName: "JBAddressRegistry"
|
|
53
53
|
})
|
|
@@ -1,177 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"format": "sphinx-sol-ct-artifact-1",
|
|
3
|
-
"merkleRoot": "0x73645f6fb745400c627c587b527553de94ee8472b637350f6d00ced9f9a780a6",
|
|
4
|
-
"address": "0x2d9b78cb37ca724cfb9b32cd8e9a5dc1c88bc7bb",
|
|
5
|
-
"sourceName": "src/JBAddressRegistry.sol",
|
|
6
|
-
"contractName": "JBAddressRegistry",
|
|
7
|
-
"chainId": "0xa4b1",
|
|
8
|
-
"abi": [
|
|
9
|
-
{
|
|
10
|
-
"inputs": [
|
|
11
|
-
{
|
|
12
|
-
"internalType": "address",
|
|
13
|
-
"name": "addr",
|
|
14
|
-
"type": "address"
|
|
15
|
-
}
|
|
16
|
-
],
|
|
17
|
-
"name": "deployerOf",
|
|
18
|
-
"outputs": [
|
|
19
|
-
{
|
|
20
|
-
"internalType": "address",
|
|
21
|
-
"name": "deployer",
|
|
22
|
-
"type": "address"
|
|
23
|
-
}
|
|
24
|
-
],
|
|
25
|
-
"stateMutability": "view",
|
|
26
|
-
"type": "function"
|
|
27
|
-
},
|
|
28
|
-
{
|
|
29
|
-
"inputs": [
|
|
30
|
-
{
|
|
31
|
-
"internalType": "address",
|
|
32
|
-
"name": "deployer",
|
|
33
|
-
"type": "address"
|
|
34
|
-
},
|
|
35
|
-
{
|
|
36
|
-
"internalType": "uint256",
|
|
37
|
-
"name": "nonce",
|
|
38
|
-
"type": "uint256"
|
|
39
|
-
}
|
|
40
|
-
],
|
|
41
|
-
"name": "registerAddress",
|
|
42
|
-
"outputs": [],
|
|
43
|
-
"stateMutability": "nonpayable",
|
|
44
|
-
"type": "function"
|
|
45
|
-
},
|
|
46
|
-
{
|
|
47
|
-
"inputs": [
|
|
48
|
-
{
|
|
49
|
-
"internalType": "address",
|
|
50
|
-
"name": "deployer",
|
|
51
|
-
"type": "address"
|
|
52
|
-
},
|
|
53
|
-
{
|
|
54
|
-
"internalType": "bytes32",
|
|
55
|
-
"name": "salt",
|
|
56
|
-
"type": "bytes32"
|
|
57
|
-
},
|
|
58
|
-
{
|
|
59
|
-
"internalType": "bytes",
|
|
60
|
-
"name": "bytecode",
|
|
61
|
-
"type": "bytes"
|
|
62
|
-
}
|
|
63
|
-
],
|
|
64
|
-
"name": "registerAddress",
|
|
65
|
-
"outputs": [],
|
|
66
|
-
"stateMutability": "nonpayable",
|
|
67
|
-
"type": "function"
|
|
68
|
-
},
|
|
69
|
-
{
|
|
70
|
-
"anonymous": false,
|
|
71
|
-
"inputs": [
|
|
72
|
-
{
|
|
73
|
-
"indexed": true,
|
|
74
|
-
"internalType": "address",
|
|
75
|
-
"name": "addr",
|
|
76
|
-
"type": "address"
|
|
77
|
-
},
|
|
78
|
-
{
|
|
79
|
-
"indexed": true,
|
|
80
|
-
"internalType": "address",
|
|
81
|
-
"name": "deployer",
|
|
82
|
-
"type": "address"
|
|
83
|
-
},
|
|
84
|
-
{
|
|
85
|
-
"indexed": false,
|
|
86
|
-
"internalType": "address",
|
|
87
|
-
"name": "caller",
|
|
88
|
-
"type": "address"
|
|
89
|
-
}
|
|
90
|
-
],
|
|
91
|
-
"name": "AddressRegistered",
|
|
92
|
-
"type": "event"
|
|
93
|
-
}
|
|
94
|
-
],
|
|
95
|
-
"args": [],
|
|
96
|
-
"solcInputHash": "8b17a7bbb5daaf8f633d28603c43b156",
|
|
97
|
-
"receipt": {
|
|
98
|
-
"type": "0x2",
|
|
99
|
-
"status": "0x1",
|
|
100
|
-
"cumulativeGasUsed": "0x97a63",
|
|
101
|
-
"logs": [
|
|
102
|
-
{
|
|
103
|
-
"address": "0xa2ea7657440875bf916cbfc0cfa88f13e38ad463",
|
|
104
|
-
"topics": [
|
|
105
|
-
"0x572f161235911da04685a68c06adf558fc7e4a36909dca394650e0adc19cc93d",
|
|
106
|
-
"0x000000000000000000000000755ff2f75a0a586ecfa2b9a3c959cb662458a105",
|
|
107
|
-
"0x000000000000000000000000647b5cbcca959a5b3f85d513faa2ba015576d8e9",
|
|
108
|
-
"0xba95fe9027aea09c07c844485d5aeb3f09b4a104b4e73a6d478df375e86551fa"
|
|
109
|
-
],
|
|
110
|
-
"data": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
111
|
-
"blockHash": "0x75e79bb45a2aa4e154db46e942dc249729cbcb785237473b454d394681da1e8b",
|
|
112
|
-
"blockNumber": "0x124ac98a",
|
|
113
|
-
"transactionHash": "0xda43fa76303262dbf1bf737b537e70d597e4c4c588c58b550c5150dc7f0cab61",
|
|
114
|
-
"transactionIndex": "0x1",
|
|
115
|
-
"logIndex": "0x0",
|
|
116
|
-
"removed": false
|
|
117
|
-
},
|
|
118
|
-
{
|
|
119
|
-
"address": "0x14293560a2dde4ffa136a647b7a2f927b0774ab6",
|
|
120
|
-
"topics": [
|
|
121
|
-
"0x6895c13664aa4f67288b25d7a21d7aaa34916e355fb9b6fae0a139a9085becb8",
|
|
122
|
-
"0x000000000000000000000000647b5cbcca959a5b3f85d513faa2ba015576d8e9"
|
|
123
|
-
],
|
|
124
|
-
"data": "0x",
|
|
125
|
-
"blockHash": "0x75e79bb45a2aa4e154db46e942dc249729cbcb785237473b454d394681da1e8b",
|
|
126
|
-
"blockNumber": "0x124ac98a",
|
|
127
|
-
"transactionHash": "0xda43fa76303262dbf1bf737b537e70d597e4c4c588c58b550c5150dc7f0cab61",
|
|
128
|
-
"transactionIndex": "0x1",
|
|
129
|
-
"logIndex": "0x1",
|
|
130
|
-
"removed": false
|
|
131
|
-
},
|
|
132
|
-
{
|
|
133
|
-
"address": "0x647b5cbcca959a5b3f85d513faa2ba015576d8e9",
|
|
134
|
-
"topics": [
|
|
135
|
-
"0xa65fb05c5808f5f389d72edeaf719ce38f4cc55c1f69ca3cbfb31c21501caa07",
|
|
136
|
-
"0x73645f6fb745400c627c587b527553de94ee8472b637350f6d00ced9f9a780a6"
|
|
137
|
-
],
|
|
138
|
-
"data": "0x0000000000000000000000000000000000000000000000000000000000000001",
|
|
139
|
-
"blockHash": "0x75e79bb45a2aa4e154db46e942dc249729cbcb785237473b454d394681da1e8b",
|
|
140
|
-
"blockNumber": "0x124ac98a",
|
|
141
|
-
"transactionHash": "0xda43fa76303262dbf1bf737b537e70d597e4c4c588c58b550c5150dc7f0cab61",
|
|
142
|
-
"transactionIndex": "0x1",
|
|
143
|
-
"logIndex": "0x2",
|
|
144
|
-
"removed": false
|
|
145
|
-
},
|
|
146
|
-
{
|
|
147
|
-
"address": "0x647b5cbcca959a5b3f85d513faa2ba015576d8e9",
|
|
148
|
-
"topics": [
|
|
149
|
-
"0x4383d976757d67ca920616be0b6430a681ea9d3dcce8d6d61d4603ca4a9bff63",
|
|
150
|
-
"0x73645f6fb745400c627c587b527553de94ee8472b637350f6d00ced9f9a780a6"
|
|
151
|
-
],
|
|
152
|
-
"data": "0x",
|
|
153
|
-
"blockHash": "0x75e79bb45a2aa4e154db46e942dc249729cbcb785237473b454d394681da1e8b",
|
|
154
|
-
"blockNumber": "0x124ac98a",
|
|
155
|
-
"transactionHash": "0xda43fa76303262dbf1bf737b537e70d597e4c4c588c58b550c5150dc7f0cab61",
|
|
156
|
-
"transactionIndex": "0x1",
|
|
157
|
-
"logIndex": "0x3",
|
|
158
|
-
"removed": false
|
|
159
|
-
}
|
|
160
|
-
],
|
|
161
|
-
"logsBloom": "0x00000000000010000040000000080000020004000000000000000000000000000000000400000000000000000040000000000000000000000000000000000000000000000000200000000000000040000000000000000000000000000000000080000000000000000800000000000000000000000000000000000000000800000800000000000100000104000000000000000000000000000020000000000000004800840000000000000000000000002200000001400000000000000004000000000002000000100000000000000000000000000000000000000000000200000000000000000008000000000000000200000000000080000000000008000000",
|
|
162
|
-
"transactionHash": "0xda43fa76303262dbf1bf737b537e70d597e4c4c588c58b550c5150dc7f0cab61",
|
|
163
|
-
"transactionIndex": "0x1",
|
|
164
|
-
"blockHash": "0x75e79bb45a2aa4e154db46e942dc249729cbcb785237473b454d394681da1e8b",
|
|
165
|
-
"blockNumber": "0x124ac98a",
|
|
166
|
-
"gasUsed": "0x97a63",
|
|
167
|
-
"effectiveGasPrice": "0xb23130",
|
|
168
|
-
"from": "0x755ff2f75a0a586ecfa2b9a3c959cb662458a105",
|
|
169
|
-
"to": "0xa2ea7657440875bf916cbfc0cfa88f13e38ad463",
|
|
170
|
-
"contractAddress": null
|
|
171
|
-
},
|
|
172
|
-
"bytecode": "0x608060405234801561000f575f80fd5b506108668061001d5f395ff3fe608060405234801561000f575f80fd5b506004361061003f575f3560e01c8063416dc73214610043578063b94417ab146100a1578063da3c8b0a146100b6575b5f80fd5b610078610051366004610759565b5f6020819052908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b6100b46100af366004610779565b6100c9565b005b6100b46100c43660046107a1565b6100e5565b5f6100d4838361019f565b90506100e081846106aa565b505050565b5f60ff60f81b858585856040516100fd929190610821565b604051908190038120610174949392916020017fff0000000000000000000000000000000000000000000000000000000000000094909416845260609290921b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001660018401526015830152603582015260550190565b604051602081830303815290604052805190602001205f1c905061019881866106aa565b5050505050565b5f6060825f03610264576040517fd60000000000000000000000000000000000000000000000000000000000000060208201527f940000000000000000000000000000000000000000000000000000000000000060218201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606086901b1660228201527f800000000000000000000000000000000000000000000000000000000000000060368201526037015b6040516020818303038152906040529050610697565b607f831161031b576040517fd60000000000000000000000000000000000000000000000000000000000000060208201527f940000000000000000000000000000000000000000000000000000000000000060218201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606086901b16602282015260f884901b7fff0000000000000000000000000000000000000000000000000000000000000016603682015260370161024e565b60ff83116103f8576040517fd70000000000000000000000000000000000000000000000000000000000000060208201527f940000000000000000000000000000000000000000000000000000000000000060218201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606086901b1660228201527f8100000000000000000000000000000000000000000000000000000000000000603682015260f884901b7fff0000000000000000000000000000000000000000000000000000000000000016603782015260380161024e565b61ffff83116104d6576040517fd80000000000000000000000000000000000000000000000000000000000000060208201527f940000000000000000000000000000000000000000000000000000000000000060218201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606086901b1660228201527f820000000000000000000000000000000000000000000000000000000000000060368201527fffff00000000000000000000000000000000000000000000000000000000000060f085901b16603782015260390161024e565b62ffffff83116105b5576040517fd90000000000000000000000000000000000000000000000000000000000000060208201527f940000000000000000000000000000000000000000000000000000000000000060218201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606086901b1660228201527f830000000000000000000000000000000000000000000000000000000000000060368201527fffffff000000000000000000000000000000000000000000000000000000000060e885901b166037820152603a0161024e565b6040517fda0000000000000000000000000000000000000000000000000000000000000060208201527f940000000000000000000000000000000000000000000000000000000000000060218201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606086901b1660228201527f840000000000000000000000000000000000000000000000000000000000000060368201527fffffffff0000000000000000000000000000000000000000000000000000000060e085901b166037820152603b0160405160208183030381529060405290505b80516020909101205f8190529392505050565b73ffffffffffffffffffffffffffffffffffffffff8281165f818152602081815260409182902080547fffffffffffffffffffffffff000000000000000000000000000000000000000016948616948517905590513381527f7d6162a71c5021da669d43dd6f106854635e56ebf51a7d028ade33473c69c0fc910160405180910390a35050565b803573ffffffffffffffffffffffffffffffffffffffff81168114610754575f80fd5b919050565b5f60208284031215610769575f80fd5b61077282610731565b9392505050565b5f806040838503121561078a575f80fd5b61079383610731565b946020939093013593505050565b5f805f80606085870312156107b4575f80fd5b6107bd85610731565b935060208501359250604085013567ffffffffffffffff808211156107e0575f80fd5b818701915087601f8301126107f3575f80fd5b813581811115610801575f80fd5b886020828501011115610812575f80fd5b95989497505060200194505050565b818382375f910190815291905056fea26469706673582212206f07b6cd7dfc40d2e815caedc2f50b5053bc3afd965325d21fc2ffeb3044113d64736f6c63430008170033",
|
|
173
|
-
"deployedBytecode": "0x608060405234801561000f575f80fd5b506004361061003f575f3560e01c8063416dc73214610043578063b94417ab146100a1578063da3c8b0a146100b6575b5f80fd5b610078610051366004610759565b5f6020819052908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b6100b46100af366004610779565b6100c9565b005b6100b46100c43660046107a1565b6100e5565b5f6100d4838361019f565b90506100e081846106aa565b505050565b5f60ff60f81b858585856040516100fd929190610821565b604051908190038120610174949392916020017fff0000000000000000000000000000000000000000000000000000000000000094909416845260609290921b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001660018401526015830152603582015260550190565b604051602081830303815290604052805190602001205f1c905061019881866106aa565b5050505050565b5f6060825f03610264576040517fd60000000000000000000000000000000000000000000000000000000000000060208201527f940000000000000000000000000000000000000000000000000000000000000060218201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606086901b1660228201527f800000000000000000000000000000000000000000000000000000000000000060368201526037015b6040516020818303038152906040529050610697565b607f831161031b576040517fd60000000000000000000000000000000000000000000000000000000000000060208201527f940000000000000000000000000000000000000000000000000000000000000060218201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606086901b16602282015260f884901b7fff0000000000000000000000000000000000000000000000000000000000000016603682015260370161024e565b60ff83116103f8576040517fd70000000000000000000000000000000000000000000000000000000000000060208201527f940000000000000000000000000000000000000000000000000000000000000060218201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606086901b1660228201527f8100000000000000000000000000000000000000000000000000000000000000603682015260f884901b7fff0000000000000000000000000000000000000000000000000000000000000016603782015260380161024e565b61ffff83116104d6576040517fd80000000000000000000000000000000000000000000000000000000000000060208201527f940000000000000000000000000000000000000000000000000000000000000060218201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606086901b1660228201527f820000000000000000000000000000000000000000000000000000000000000060368201527fffff00000000000000000000000000000000000000000000000000000000000060f085901b16603782015260390161024e565b62ffffff83116105b5576040517fd90000000000000000000000000000000000000000000000000000000000000060208201527f940000000000000000000000000000000000000000000000000000000000000060218201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606086901b1660228201527f830000000000000000000000000000000000000000000000000000000000000060368201527fffffff000000000000000000000000000000000000000000000000000000000060e885901b166037820152603a0161024e565b6040517fda0000000000000000000000000000000000000000000000000000000000000060208201527f940000000000000000000000000000000000000000000000000000000000000060218201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606086901b1660228201527f840000000000000000000000000000000000000000000000000000000000000060368201527fffffffff0000000000000000000000000000000000000000000000000000000060e085901b166037820152603b0160405160208183030381529060405290505b80516020909101205f8190529392505050565b73ffffffffffffffffffffffffffffffffffffffff8281165f818152602081815260409182902080547fffffffffffffffffffffffff000000000000000000000000000000000000000016948616948517905590513381527f7d6162a71c5021da669d43dd6f106854635e56ebf51a7d028ade33473c69c0fc910160405180910390a35050565b803573ffffffffffffffffffffffffffffffffffffffff81168114610754575f80fd5b919050565b5f60208284031215610769575f80fd5b61077282610731565b9392505050565b5f806040838503121561078a575f80fd5b61079383610731565b946020939093013593505050565b5f805f80606085870312156107b4575f80fd5b6107bd85610731565b935060208501359250604085013567ffffffffffffffff808211156107e0575f80fd5b818701915087601f8301126107f3575f80fd5b813581811115610801575f80fd5b886020828501011115610812575f80fd5b95989497505060200194505050565b818382375f910190815291905056fea26469706673582212206f07b6cd7dfc40d2e815caedc2f50b5053bc3afd965325d21fc2ffeb3044113d64736f6c63430008170033",
|
|
174
|
-
"metadata": "{\"compiler\":{\"version\":\"0.8.23+commit.f704f362\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"deployer\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"AddressRegistered\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"deployerOf\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"deployer\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"deployer\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"}],\"name\":\"registerAddress\",\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"deployer\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"salt\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"bytecode\",\"type\":\"bytes\"}],\"name\":\"registerAddress\",\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"registerAddress(address,bytes32,bytes)\":{\"details\":\"The contract must be deployed using `create2`.The `create2` salt is determined by the deployer's logic. The deployment bytecode can be retrieved offchain (from the deployment transaction) or onchain (with `abi.encodePacked(type(deployedContract).creationCode, abi.encode(constructorArguments))`).\",\"params\":{\"bytecode\":\"The contract's deployment bytecode, including the constructor arguments.\",\"deployer\":\"The address of the contract's deployer.\",\"salt\":\"The `create2` salt used to deploy the contract.\"}},\"registerAddress(address,uint256)\":{\"details\":\"The contract must be deployed using `create`.\",\"params\":{\"deployer\":\"The address of the contract's deployer.\",\"nonce\":\"The nonce used to deploy the contract.\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"deployerOf(address)\":{\"notice\":\"Returns the deployer of a given contract which has been registered.\"},\"registerAddress(address,bytes32,bytes)\":{\"notice\":\"Register a deployed contract's address.\"},\"registerAddress(address,uint256)\":{\"notice\":\"Register a deployed contract's address.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/JBAddressRegistry.sol\":\"JBAddressRegistry\"},\"evmVersion\":\"shanghai\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000000},\"remappings\":[\"@eth-optimism/=node_modules/@eth-optimism/\",\"@openzeppelin/=node_modules/@openzeppelin/\",\"@sphinx-labs/contracts/=lib/sphinx/packages/contracts/contracts/foundry/\",\"ds-test/=lib/forge-std/lib/ds-test/src/\",\"forge-std/=lib/forge-std/src/\",\"hardhat/=node_modules/hardhat/\",\"solmate/=node_modules/solmate/\",\"sphinx/=lib/sphinx/packages/contracts/contracts/forge-std/src/\"]},\"sources\":{\"src/JBAddressRegistry.sol\":{\"keccak256\":\"0x938e275702ab7077760775dbadb528e18614547863daf131d9561cf6a675c7ad\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://aae0e7665c7e284c9ff8e20ea5a03f75a25d69e28bec28596617a37fba68274b\",\"dweb:/ipfs/QmTy4UP1neJ81D8uENk5TwBcMc7c9yXw7QZ2S7ij1jcVzH\"]},\"src/interfaces/IJBAddressRegistry.sol\":{\"keccak256\":\"0x984b1f4a0301ee5a5fe44d6d228aa0a60161e0ff69509ef3d5f829c4b154e423\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://c1e46de177797b8585c8030377f470ac6737ddf3496f0a3a6b16e01ad7712dab\",\"dweb:/ipfs/QmW771SQMskbmJG9GHJPMhzJGTFpU3JVj2YxFtLSaAb3Xk\"]}},\"version\":1}",
|
|
175
|
-
"gitCommit": "922b48185d8a792b44854cf6d3257339a9d73eaa",
|
|
176
|
-
"history": []
|
|
177
|
-
}
|