julien/lovepublic Fork
⑂ 6e1128e
Commits
⬇ Clone ▾
git clone https://git.rickub.com/julien/love.git
git clone ssh://git@rickub.com/julien/love.git

Host key fingerprint (ed25519): SHA256:iycHnxEyq0Q7uyVpB7JlznP0G7JrTPXLYRcAU5CSLhc — verify it before your first connect.

Download ZIP

Merge 13-add-supported-networks-doc into main

rickub committed 2026-09-18T18:30:25Z Browse files
6e1128e parent: b20d6e4
modified CHANGELOG.md +7 -0
@@ -54,6 +54,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
5454
5555 ### Added
5656
57+- `docs/SUPPORTED_NETWORKS.md`, listing the 14 chains the allowlist covers and
58+ the 2026-09-18 survey of other candidates. Six OP Stack chains (Orderly, Lyra,
59+ Shape, Swan Chain, HashKey Chain, Settlus) run a reviewed hash and only need
60+ their chain ID paired; six more (BOB, Cyber, Metal L2, Fraxtal, Funki,
61+ Superseed) need a new exact hash; nine were unreachable; the rest are
62+ excluded by design. Custom-gas-token chains still need their native currency
63+ checked before any of them is added.
5764 - The README lists the 14 allowlisted chains with their chain IDs and wETH
5865 implementations, so where LOVE can be deployed is visible without reading
5966 `WETHRegistry.sol`.
@@ -54,6 +54,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
54 54
55 ### Added55 ### Added
56 56
57+- `docs/SUPPORTED_NETWORKS.md`, listing the 14 chains the allowlist covers and
58+ the 2026-09-18 survey of other candidates. Six OP Stack chains (Orderly, Lyra,
59+ Shape, Swan Chain, HashKey Chain, Settlus) run a reviewed hash and only need
60+ their chain ID paired; six more (BOB, Cyber, Metal L2, Fraxtal, Funki,
61+ Superseed) need a new exact hash; nine were unreachable; the rest are
62+ excluded by design. Custom-gas-token chains still need their native currency
63+ checked before any of them is added.
57 - The README lists the 14 allowlisted chains with their chain IDs and wETH64 - The README lists the 14 allowlisted chains with their chain IDs and wETH
58 implementations, so where LOVE can be deployed is visible without reading65 implementations, so where LOVE can be deployed is visible without reading
59 `WETHRegistry.sol`.66 `WETHRegistry.sol`.
added docs/SUPPORTED_NETWORKS.md +143 -0
new file mode 100644
@@ -0,0 +1,143 @@
1+# Supported Networks
2+
3+Which chains LOVE can deploy on today, and which other chains a 2026-09-18 survey found could be added to the wETH allowlist.
4+
5+## Contents
6+
7+- [Supported Networks](#supported-networks)
8+ - [Contents](#contents)
9+ - [How support is decided](#how-support-is-decided)
10+ - [Supported today](#supported-today)
11+ - [Survey of other networks](#survey-of-other-networks)
12+ - [A. Reviewed hash, chain ID missing](#a-reviewed-hash-chain-id-missing)
13+ - [B. New exact hash, same family](#b-new-exact-hash-same-family)
14+ - [C. Unreachable](#c-unreachable)
15+ - [D. Leads not yet checked](#d-leads-not-yet-checked)
16+ - [E. Excluded by design](#e-excluded-by-design)
17+ - [Extending the allowlist](#extending-the-allowlist)
18+ - [Further reading](#further-reading)
19+
20+## How support is decided
21+
22+A chain is supported when [`WETHRegistry`](../src/WETHRegistry.sol) will accept its [wETH](https://weth.io/): the candidate's `EXTCODEHASH` must be on the compile-time allowlist *paired with that chain's ID*, and it must survive a one-wei deposit/withdraw round trip. The design and its trade-offs are in [MULTICHAIN.md](MULTICHAIN.md); the bytecode survey behind the list is in [weth-codehashes.md](notes/weth-codehashes.md).
23+
24+Two consequences shape everything below:
25+
26+- A hash that is already reviewed is not enough. If the chain ID is not paired with it in `isKnownImplementation`, registration reverts.
27+- Adding an entry means publishing a new registry, which changes `Love`'s creation code and therefore its address on every chain. It is cheap before launch and expensive after.
28+
29+## Supported today
30+
31+14 chains, 5 implementations, 10 exact codehashes. Hashes are shown truncated; the full values are in `isKnownImplementation`, and [`script/weth-codehashes.sh`](../script/weth-codehashes.sh) re-derives them from chain state.
32+
33+| Implementation | Codehash | Chain | Chain ID |
34+| ------------------------------------------------------------------ | ------------ | -------------- | -------- |
35+| [OP Stack legacy WETH9](https://specs.optimism.io/protocol/predeploys.html) (2041 B, solc 0.5.17) | `0x779bbf2a` | Optimism | 10 |
36+| | `0x8a3a1f6a` | Base | 8453 |
37+| | `0x8a3a1f6a` | Mode | 34443 |
38+| | `0x8a3a1f6a` | Zora | 7777777 |
39+| | `0x557c8e14` | World Chain | 480 |
40+| | `0xf35fe602` | Lisk | 1135 |
41+| [Canonical WETH9](https://github.com/gnosis/canonical-weth) (3124 B, solc 0.4.19) | `0xd0a06b12` | Ethereum | 1 |
42+| | `0xa670ec6c` | Linea | 59144 |
43+| | `0x032e9cab` | Polygon zkEVM | 1101 |
44+| OP Stack WETH (2865 B, solc 0.8.15) | `0xd0f1614c` | Unichain | 130 |
45+| | `0xd0f1614c` | Soneium | 1868 |
46+| | `0xd0f1614c` | Ink | 57073 |
47+| Taiko (3204 B) | `0x9f3d9508` | Taiko | 167000 |
48+| Scroll (5871 B) | `0xe8c40733` | Scroll | 534352 |
49+
50+The OP Stack legacy WETH9 chains run byte-identical code and differ only inside [solc's metadata](https://docs.soliditylang.org/en/latest/metadata.html) blob, which is why one implementation carries four hashes.
51+
52+## Survey of other networks
53+
54+Run on 2026-09-18. Every OP Stack mainnet in the [superchain registry](https://github.com/ethereum-optimism/superchain-registry/blob/main/chainList.json) was queried with `eth_getCode` at the [WETH predeploy](https://specs.optimism.io/protocol/predeploys.html) `0x4200000000000000000000000000000000000006`. The code was hashed with `keccak256` and compared with the allowlist; where the hash was new, it was compared with the known families after stripping the metadata blob. Base is allowlisted but is not in the registry's chain list, so it was not part of this run.
55+
56+Web search alone did not turn up a list of chains per implementation, so the survey is bounded by what the registry and the public RPCs expose. For non-OP-Stack families it found nothing beyond the chains already supported.
57+
58+**Check the gas token before adding any of these.** The predeploy wraps whatever the chain's native currency is. On a custom-gas-token chain that is not ETH, so the round-trip probe would pass while wrapping the wrong asset. This is exactly what pairing hashes with chain IDs is meant to stop. I believe Fraxtal (frxETH), HashKey Chain (HSK), Swan Chain (SWAN) and Settlus (SETT) fall in this group, but that is unverified and has to be confirmed per chain.
59+
60+### A. Reviewed hash, chain ID missing
61+
62+Adding these needs only new chain IDs next to hashes that are already reviewed.
63+
64+| Chain | Chain ID | Implementation | Hash matches |
65+| ------------- | -------- | --------------------- | ------------ |
66+| Orderly | 291 | OP Stack legacy WETH9 | Base, Mode, Zora |
67+| Lyra | 957 | OP Stack legacy WETH9 | Base, Mode, Zora |
68+| Shape | 360 | OP Stack legacy WETH9 | World Chain |
69+| Swan Chain | 254 | OP Stack legacy WETH9 | Lisk |
70+| HashKey Chain | 177 | OP Stack WETH | Unichain, Soneium, Ink |
71+| Settlus | 5371 | OP Stack WETH | Unichain, Soneium, Ink |
72+
73+### B. New exact hash, same family
74+
75+Each needs a new codehash entry. The code is the same implementation, differing in metadata or, for Funki and Superseed, a version string.
76+
77+| Chain | Chain ID | Implementation | New hash | Note |
78+| ------------------- | -------- | --------------------- | ------------ | ---- |
79+| BOB | 60808 | OP Stack legacy WETH9 | `0x52e157d1` | Metadata only. |
80+| Cyber | 7560 | OP Stack legacy WETH9 | `0x52e157d1` | Same hash as BOB. |
81+| Metal L2 | 1750 | OP Stack legacy WETH9 | `0x52e157d1` | Same hash as BOB. |
82+| Fraxtal (predeploy) | 252 | OP Stack legacy WETH9 | `0x83f731a1` | Gas token is frxETH, so probably not. The [weth-codehashes.md](notes/weth-codehashes.md) survey looked at the proxy at `0xFC00…0006` instead. |
83+| Funki | 33979 | OP Stack WETH | `0x4070f345` | 8 bytes differ from Unichain's, all in `version()`: `1.0.0` instead of `1.0.0-beta.1`. |
84+| Superseed | 5330 | OP Stack WETH | `0x4070f345` | Same hash as Funki. |
85+
86+### C. Unreachable
87+
88+The public RPC listed in the registry did not answer. Their status is unknown.
89+
90+| Chain | Chain ID | Failure |
91+| -------------- | -------- | ------- |
92+| Binary | 624 | TLS hostname mismatch |
93+| Polynomial | 8008 | TLS hostname mismatch |
94+| Silent Data | 380929 | TLS hostname mismatch |
95+| Ethernity | 183 | DNS failure |
96+| RACE | 6805 | DNS failure |
97+| Redstone | 690 | DNS failure |
98+| Xterio (ETH) | 2702128 | DNS failure |
99+| Mint | 185 | Timeout |
100+| Automata | 65536 | Retired; the RPC says so |
101+
102+### D. Leads not yet checked
103+
104+No wETH address was in hand, so nothing was hashed.
105+
106+- **Monad, MegaETH, X Layer, Robinhood Chain, Tempo.** Listed on [Uniswap's V3 deployments](http://developers.uniswap.org/llms.mdx/docs/protocols/v3/deployments) page, which gives no wETH addresses.
107+- **Sonic.** A [WETH at `0x50c4…634b`](https://sonicscan.org/address/0x50c42dEAcD8Fc9773493ED674b675bE577f2634b) is labelled official. Sonic's gas token is S, so it is probably bridged.
108+- **Scroll SDK chains.** Chains built with the [Scroll SDK](https://docs.scroll.io/en/sdk/) get the same predeploy at `0x5300…0004`. No live mainnet was found.
109+- **Taiko.** [Taikoscan](https://taikoscan.io/address/0xa51894664a773981c6c112c43ce576f315d5b1b6) lists its wETH as WETH9 compiled with solc 0.4.22. No other chain using it was found.
110+- **Canonical WETH9.** Only a match where a chain deployed byte-identical code; there is no registry to enumerate that from.
111+
112+### E. Excluded by design
113+
114+These cannot be added without changing the design. The reasoning is in [weth-codehashes.md](notes/weth-codehashes.md).
115+
116+| Reason | Chains |
117+| ----------------------- | ------ |
118+| Upgradeable proxy: the codehash commits to a forwarder, not to behaviour | Arbitrum One, Gnosis, Blast, Fraxtal (`0xFC00…0006`) |
119+| Bridged ETH with no `deposit()`/`withdraw()`: the round-trip probe cannot run | BNB Chain, opBNB, Polygon PoS, Metis, Mantle, Celo, Avalanche, Berachain, Boba |
120+| `EXTCODEHASH` is a zk bytecode hash, not `keccak256` of the runtime code | zkSync Era |
121+
122+Celo's predeploy has `deposit()`/`withdraw()` but different code, and its gas token is CELO. Boba's is 2814 bytes with no `deposit()`/`withdraw()`.
123+
124+## Extending the allowlist
125+
126+Batch everything into one registry revision, and do it before launch:
127+
128+1. Confirm each chain's gas token is ETH.
129+2. Add the section A chain IDs next to their existing hashes.
130+3. Add the section B hashes with their chain IDs.
131+4. Re-run [`script/weth-codehashes.sh`](../script/weth-codehashes.sh) so every entry is reproducible from chain state.
132+5. Redeploy the registry, update `REGISTRY` in `Love`, and re-run [`script/multichain-check.sh`](../script/multichain-check.sh).
133+
134+Step 5 changes `Love`'s address everywhere. Existing deployments are untouched, but they are no longer the address the new registry produces.
135+
136+## Further reading
137+
138+- [MULTICHAIN.md](MULTICHAIN.md)
139+- [weth-codehashes.md](notes/weth-codehashes.md)
140+- [Superchain registry](https://docs.optimism.io/op-stack/protocol/superchain-registry)
141+- [OP Stack predeploys](https://specs.optimism.io/protocol/predeploys.html)
142+- [Scroll SDK](https://docs.scroll.io/en/sdk/)
143+- [EIP-1052: EXTCODEHASH](https://eips.ethereum.org/EIPS/eip-1052)
new file mode 100644
@@ -0,0 +1,143 @@
1+# Supported Networks
2+
3+Which chains LOVE can deploy on today, and which other chains a 2026-09-18 survey found could be added to the wETH allowlist.
4+
5+## Contents
6+
7+- [Supported Networks](#supported-networks)
8+ - [Contents](#contents)
9+ - [How support is decided](#how-support-is-decided)
10+ - [Supported today](#supported-today)
11+ - [Survey of other networks](#survey-of-other-networks)
12+ - [A. Reviewed hash, chain ID missing](#a-reviewed-hash-chain-id-missing)
13+ - [B. New exact hash, same family](#b-new-exact-hash-same-family)
14+ - [C. Unreachable](#c-unreachable)
15+ - [D. Leads not yet checked](#d-leads-not-yet-checked)
16+ - [E. Excluded by design](#e-excluded-by-design)
17+ - [Extending the allowlist](#extending-the-allowlist)
18+ - [Further reading](#further-reading)
19+
20+## How support is decided
21+
22+A chain is supported when [`WETHRegistry`](../src/WETHRegistry.sol) will accept its [wETH](https://weth.io/): the candidate's `EXTCODEHASH` must be on the compile-time allowlist *paired with that chain's ID*, and it must survive a one-wei deposit/withdraw round trip. The design and its trade-offs are in [MULTICHAIN.md](MULTICHAIN.md); the bytecode survey behind the list is in [weth-codehashes.md](notes/weth-codehashes.md).
23+
24+Two consequences shape everything below:
25+
26+- A hash that is already reviewed is not enough. If the chain ID is not paired with it in `isKnownImplementation`, registration reverts.
27+- Adding an entry means publishing a new registry, which changes `Love`'s creation code and therefore its address on every chain. It is cheap before launch and expensive after.
28+
29+## Supported today
30+
31+14 chains, 5 implementations, 10 exact codehashes. Hashes are shown truncated; the full values are in `isKnownImplementation`, and [`script/weth-codehashes.sh`](../script/weth-codehashes.sh) re-derives them from chain state.
32+
33+| Implementation | Codehash | Chain | Chain ID |
34+| ------------------------------------------------------------------ | ------------ | -------------- | -------- |
35+| [OP Stack legacy WETH9](https://specs.optimism.io/protocol/predeploys.html) (2041 B, solc 0.5.17) | `0x779bbf2a` | Optimism | 10 |
36+| | `0x8a3a1f6a` | Base | 8453 |
37+| | `0x8a3a1f6a` | Mode | 34443 |
38+| | `0x8a3a1f6a` | Zora | 7777777 |
39+| | `0x557c8e14` | World Chain | 480 |
40+| | `0xf35fe602` | Lisk | 1135 |
41+| [Canonical WETH9](https://github.com/gnosis/canonical-weth) (3124 B, solc 0.4.19) | `0xd0a06b12` | Ethereum | 1 |
42+| | `0xa670ec6c` | Linea | 59144 |
43+| | `0x032e9cab` | Polygon zkEVM | 1101 |
44+| OP Stack WETH (2865 B, solc 0.8.15) | `0xd0f1614c` | Unichain | 130 |
45+| | `0xd0f1614c` | Soneium | 1868 |
46+| | `0xd0f1614c` | Ink | 57073 |
47+| Taiko (3204 B) | `0x9f3d9508` | Taiko | 167000 |
48+| Scroll (5871 B) | `0xe8c40733` | Scroll | 534352 |
49+
50+The OP Stack legacy WETH9 chains run byte-identical code and differ only inside [solc's metadata](https://docs.soliditylang.org/en/latest/metadata.html) blob, which is why one implementation carries four hashes.
51+
52+## Survey of other networks
53+
54+Run on 2026-09-18. Every OP Stack mainnet in the [superchain registry](https://github.com/ethereum-optimism/superchain-registry/blob/main/chainList.json) was queried with `eth_getCode` at the [WETH predeploy](https://specs.optimism.io/protocol/predeploys.html) `0x4200000000000000000000000000000000000006`. The code was hashed with `keccak256` and compared with the allowlist; where the hash was new, it was compared with the known families after stripping the metadata blob. Base is allowlisted but is not in the registry's chain list, so it was not part of this run.
55+
56+Web search alone did not turn up a list of chains per implementation, so the survey is bounded by what the registry and the public RPCs expose. For non-OP-Stack families it found nothing beyond the chains already supported.
57+
58+**Check the gas token before adding any of these.** The predeploy wraps whatever the chain's native currency is. On a custom-gas-token chain that is not ETH, so the round-trip probe would pass while wrapping the wrong asset. This is exactly what pairing hashes with chain IDs is meant to stop. I believe Fraxtal (frxETH), HashKey Chain (HSK), Swan Chain (SWAN) and Settlus (SETT) fall in this group, but that is unverified and has to be confirmed per chain.
59+
60+### A. Reviewed hash, chain ID missing
61+
62+Adding these needs only new chain IDs next to hashes that are already reviewed.
63+
64+| Chain | Chain ID | Implementation | Hash matches |
65+| ------------- | -------- | --------------------- | ------------ |
66+| Orderly | 291 | OP Stack legacy WETH9 | Base, Mode, Zora |
67+| Lyra | 957 | OP Stack legacy WETH9 | Base, Mode, Zora |
68+| Shape | 360 | OP Stack legacy WETH9 | World Chain |
69+| Swan Chain | 254 | OP Stack legacy WETH9 | Lisk |
70+| HashKey Chain | 177 | OP Stack WETH | Unichain, Soneium, Ink |
71+| Settlus | 5371 | OP Stack WETH | Unichain, Soneium, Ink |
72+
73+### B. New exact hash, same family
74+
75+Each needs a new codehash entry. The code is the same implementation, differing in metadata or, for Funki and Superseed, a version string.
76+
77+| Chain | Chain ID | Implementation | New hash | Note |
78+| ------------------- | -------- | --------------------- | ------------ | ---- |
79+| BOB | 60808 | OP Stack legacy WETH9 | `0x52e157d1` | Metadata only. |
80+| Cyber | 7560 | OP Stack legacy WETH9 | `0x52e157d1` | Same hash as BOB. |
81+| Metal L2 | 1750 | OP Stack legacy WETH9 | `0x52e157d1` | Same hash as BOB. |
82+| Fraxtal (predeploy) | 252 | OP Stack legacy WETH9 | `0x83f731a1` | Gas token is frxETH, so probably not. The [weth-codehashes.md](notes/weth-codehashes.md) survey looked at the proxy at `0xFC00…0006` instead. |
83+| Funki | 33979 | OP Stack WETH | `0x4070f345` | 8 bytes differ from Unichain's, all in `version()`: `1.0.0` instead of `1.0.0-beta.1`. |
84+| Superseed | 5330 | OP Stack WETH | `0x4070f345` | Same hash as Funki. |
85+
86+### C. Unreachable
87+
88+The public RPC listed in the registry did not answer. Their status is unknown.
89+
90+| Chain | Chain ID | Failure |
91+| -------------- | -------- | ------- |
92+| Binary | 624 | TLS hostname mismatch |
93+| Polynomial | 8008 | TLS hostname mismatch |
94+| Silent Data | 380929 | TLS hostname mismatch |
95+| Ethernity | 183 | DNS failure |
96+| RACE | 6805 | DNS failure |
97+| Redstone | 690 | DNS failure |
98+| Xterio (ETH) | 2702128 | DNS failure |
99+| Mint | 185 | Timeout |
100+| Automata | 65536 | Retired; the RPC says so |
101+
102+### D. Leads not yet checked
103+
104+No wETH address was in hand, so nothing was hashed.
105+
106+- **Monad, MegaETH, X Layer, Robinhood Chain, Tempo.** Listed on [Uniswap's V3 deployments](http://developers.uniswap.org/llms.mdx/docs/protocols/v3/deployments) page, which gives no wETH addresses.
107+- **Sonic.** A [WETH at `0x50c4…634b`](https://sonicscan.org/address/0x50c42dEAcD8Fc9773493ED674b675bE577f2634b) is labelled official. Sonic's gas token is S, so it is probably bridged.
108+- **Scroll SDK chains.** Chains built with the [Scroll SDK](https://docs.scroll.io/en/sdk/) get the same predeploy at `0x5300…0004`. No live mainnet was found.
109+- **Taiko.** [Taikoscan](https://taikoscan.io/address/0xa51894664a773981c6c112c43ce576f315d5b1b6) lists its wETH as WETH9 compiled with solc 0.4.22. No other chain using it was found.
110+- **Canonical WETH9.** Only a match where a chain deployed byte-identical code; there is no registry to enumerate that from.
111+
112+### E. Excluded by design
113+
114+These cannot be added without changing the design. The reasoning is in [weth-codehashes.md](notes/weth-codehashes.md).
115+
116+| Reason | Chains |
117+| ----------------------- | ------ |
118+| Upgradeable proxy: the codehash commits to a forwarder, not to behaviour | Arbitrum One, Gnosis, Blast, Fraxtal (`0xFC00…0006`) |
119+| Bridged ETH with no `deposit()`/`withdraw()`: the round-trip probe cannot run | BNB Chain, opBNB, Polygon PoS, Metis, Mantle, Celo, Avalanche, Berachain, Boba |
120+| `EXTCODEHASH` is a zk bytecode hash, not `keccak256` of the runtime code | zkSync Era |
121+
122+Celo's predeploy has `deposit()`/`withdraw()` but different code, and its gas token is CELO. Boba's is 2814 bytes with no `deposit()`/`withdraw()`.
123+
124+## Extending the allowlist
125+
126+Batch everything into one registry revision, and do it before launch:
127+
128+1. Confirm each chain's gas token is ETH.
129+2. Add the section A chain IDs next to their existing hashes.
130+3. Add the section B hashes with their chain IDs.
131+4. Re-run [`script/weth-codehashes.sh`](../script/weth-codehashes.sh) so every entry is reproducible from chain state.
132+5. Redeploy the registry, update `REGISTRY` in `Love`, and re-run [`script/multichain-check.sh`](../script/multichain-check.sh).
133+
134+Step 5 changes `Love`'s address everywhere. Existing deployments are untouched, but they are no longer the address the new registry produces.
135+
136+## Further reading
137+
138+- [MULTICHAIN.md](MULTICHAIN.md)
139+- [weth-codehashes.md](notes/weth-codehashes.md)
140+- [Superchain registry](https://docs.optimism.io/op-stack/protocol/superchain-registry)
141+- [OP Stack predeploys](https://specs.optimism.io/protocol/predeploys.html)
142+- [Scroll SDK](https://docs.scroll.io/en/sdk/)
143+- [EIP-1052: EXTCODEHASH](https://eips.ethereum.org/EIPS/eip-1052)