julien/lovepublic Fork
⑂ main
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
README.md

Love

The one and only LOVE token.

Install

forge install
cp .env.example .env

Build

forge build

Test

forge test

The private pool has an end-to-end run against a local anvil, which needs anvil and forge on your PATH:

cd zk && pnpm install && pnpm e2e

Deploy

Deployment uses CREATE2, so the token has the same address on every EVM network.
Bringing up a chain is registry, then registration, then token — run() does
all three and skips whichever has already happened.

forge script script/Love.s.sol:LoveScript --sig 'predict()'   # print the address

WETH=0x4200000000000000000000000000000000000006 \
forge script script/Love.s.sol:LoveScript \
  --rpc-url base_sepolia \
  --account "$DEPLOYER_ACCOUNT" \
  --broadcast \
  --verify

WETH defaults to the OP Stack predeploy and is ignored once a wETH is
registered. Registration sends 1 wei, which stays in the registry.

To check determinism for real, deploy on two local chains and compare:

./script/multichain-check.sh

It starts two anvil nodes (chain IDs 31337 and 31338), gives them different
wETH implementations at different addresses, brings both up, and exits
non-zero if the two LOVE addresses differ. Override PORT_A, PORT_B,
CHAIN_ID_A, CHAIN_ID_B or SALT as needed.

Privacy

Besides the plain deposit(uint256), LOVE has a private pool. deposit(bytes32 commitment) locks 0.01 wETH against a note, and claim(proof, root, nullifierHash, recipient) pays its LOVE to any address whose owner can prove,
in zero knowledge, that they hold a note in the pool, without saying which. The
circuit and its Groth16 setup live in
zk/. The setup has a single contributor, so treat it as testnet-grade.
Full workflow, what the pool hides and its limits: see docs/ZK.md.

How wETH is chosen

LOVE is pegged to wETH, and that wETH is not a constructor argument. It is read
at construction time from WETHRegistry, which accepts an address only if its
EXTCODEHASH is one of ten reviewed wETH implementations and it survives a
one-wei deposit/withdraw round trip. Registration is permissionless, ownerless
and write-once.

Two things follow. A LOVE instance can never be bound to a typo, a lookalike
ERC-20 or an unreviewed wrapper. And because wETH is no longer in the creation
code, the creation code is byte-identical everywhere, so CREATE2 gives LOVE one
address on every chain instead of one per wETH deployment.

The allowlist covers 14 chains across 5 implementations:

Chain Chain ID wETH implementation
Optimism 10 OP Stack legacy WETH9
Base 8453 OP Stack legacy WETH9
Mode 34443 OP Stack legacy WETH9
Zora 7777777 OP Stack legacy WETH9
World Chain 480 OP Stack legacy WETH9
Lisk 1135 OP Stack legacy WETH9
Ethereum 1 Canonical WETH9
Linea 59144 Canonical WETH9
Polygon zkEVM 1101 Canonical WETH9
Unichain 130 OP Stack WETH
Soneium 1868 OP Stack WETH
Ink 57073 OP Stack WETH
Taiko 167000 Taiko
Scroll 534352 Scroll

Deployment is blocked elsewhere, on purpose: the remaining chains either carry
bridged ETH with no deposit()/withdraw(), or put wETH behind an upgradeable
proxy, where a codehash commits to a forwarder rather than to behaviour. To
re-derive the list from chain state:

./script/weth-codehashes.sh

One caveat worth knowing before you trust an instance: the gate proves a
candidate is a reviewed wETH implementation, not that it is the wETH a
chain's ecosystem uses. Anyone can deploy a fresh WETH9 copy — same bytecode,
no liquidity — and register it first. Nothing is stealable, since it is real
WETH9 and fully redeemable, but check WETH() against the chain's canonical
address before treating a deployment as the real one.

Full design rationale, the allowlist's contents, and how to verify determinism
yourself: see docs/MULTICHAIN.md.

Docs

  • Multichain deployment — CREATE2, the codehash allowlist, and verifying determinism
  • ZK pool — sending LOVE privately with Groth16 proofs, and where the trust and capacity limits are
  • Supported networks — where LOVE deploys today and what could be added

License

GPL-3.0

Contact

Julien Béranger (GitHub)