julien/lovepublic Fork 0
1c407d3
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.

document create2 deployment

julienbrg committed 2026-09-17T21:07:44+02:00 Browse files
1c407d3 parent: 9056150
modified CHANGELOG.md +5 -1
@@ -13,7 +13,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1313 - `Love`, an ERC-20 token (`LOVE`, 18 decimals) on OpenZeppelin v5, with an
1414 unrestricted public `mint(address,uint256)` — anyone can mint any amount.
1515 - Metadata, mint, transfer, approve/`transferFrom`, revert and fuzz tests.
16-- Deployment script `script/Love.s.sol`.
16+- Deployment script `script/Love.s.sol`, deploying with CREATE2 through the
17+ canonical deterministic deployer so `Love` gets the same address on every EVM
18+ network; salt defaults to `keccak256("LOVE")` and is overridable via `SALT`.
19+- `predict()` entrypoint printing the deployment address without broadcasting,
20+ and CREATE2 tests pinning address determinism across chain IDs.
1721 - `foundry.toml` with pinned solc 0.8.30, optimizer, fmt rules, fuzz/invariant
1822 defaults, and Base Sepolia RPC/Etherscan endpoints driven by env vars.
1923 - `remappings.txt` for `@openzeppelin/contracts/` and `forge-std/`.
@@ -13,7 +13,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
13 - `Love`, an ERC-20 token (`LOVE`, 18 decimals) on OpenZeppelin v5, with an13 - `Love`, an ERC-20 token (`LOVE`, 18 decimals) on OpenZeppelin v5, with an
14 unrestricted public `mint(address,uint256)` — anyone can mint any amount.14 unrestricted public `mint(address,uint256)` — anyone can mint any amount.
15 - Metadata, mint, transfer, approve/`transferFrom`, revert and fuzz tests.15 - Metadata, mint, transfer, approve/`transferFrom`, revert and fuzz tests.
16-- Deployment script `script/Love.s.sol`.16+- Deployment script `script/Love.s.sol`, deploying with CREATE2 through the
17+ canonical deterministic deployer so `Love` gets the same address on every EVM
18+ network; salt defaults to `keccak256("LOVE")` and is overridable via `SALT`.
19+- `predict()` entrypoint printing the deployment address without broadcasting,
20+ and CREATE2 tests pinning address determinism across chain IDs.
17 - `foundry.toml` with pinned solc 0.8.30, optimizer, fmt rules, fuzz/invariant21 - `foundry.toml` with pinned solc 0.8.30, optimizer, fmt rules, fuzz/invariant
18 defaults, and Base Sepolia RPC/Etherscan endpoints driven by env vars.22 defaults, and Base Sepolia RPC/Etherscan endpoints driven by env vars.
19 - `remappings.txt` for `@openzeppelin/contracts/` and `forge-std/`.23 - `remappings.txt` for `@openzeppelin/contracts/` and `forge-std/`.
modified README.md +35 -1
@@ -35,6 +35,20 @@ anvil # local node
3535
3636 ## Deploy
3737
38+`Love` is deployed with CREATE2 through the canonical
39+[deterministic deployer](https://github.com/Arachnid/deterministic-deployment-proxy)
40+at `0x4e59b44847b379578588920cA78FbF26c0B4956C`, so it gets **the same address on
41+every EVM network**. The address derives from the salt and the creation code
42+only — not from the deployer account or its nonce.
43+
44+Check the address before spending gas:
45+
46+```shell
47+forge script script/Love.s.sol:LoveScript --sig 'predict()'
48+```
49+
50+Then deploy:
51+
3852 ```shell
3953 forge script script/Love.s.sol:LoveScript \
4054 --rpc-url base_sepolia \
@@ -43,7 +57,27 @@ forge script script/Love.s.sol:LoveScript \
4357 --verify
4458 ```
4559
46-Drop `--broadcast` for a dry run.
60+Drop `--broadcast` for a dry run. Re-running against a network where the token
61+already exists is a no-op.
62+
63+The salt defaults to `keccak256("LOVE")`; override it — to mine a vanity address,
64+say — with `SALT=0x… forge script …`. The same salt must be used on every
65+network.
66+
67+### Keeping the address stable
68+
69+The creation code, and therefore the address, changes if any of these change:
70+
71+- the contract source (`src/Love.sol`) or its OpenZeppelin version,
72+- `solc` (pinned to 0.8.30 in `foundry.toml`),
73+- optimizer settings (`optimizer = true`, `optimizer_runs = 200`, `via_ir = false`),
74+- `bytecode_hash` (set to `none`, which keeps the metadata hash out of the
75+ bytecode so paths and compiler metadata don't leak into the address).
76+
77+Treat those as frozen once the token is deployed anywhere.
78+
79+Chains lacking the deterministic deployer — zkSync-style chains in particular,
80+where CREATE2 addresses are computed differently — cannot match this address.
4781
4882 ## Layout
4983
@@ -35,6 +35,20 @@ anvil # local node
35 35
36 ## Deploy36 ## Deploy
37 37
38+`Love` is deployed with CREATE2 through the canonical
39+[deterministic deployer](https://github.com/Arachnid/deterministic-deployment-proxy)
40+at `0x4e59b44847b379578588920cA78FbF26c0B4956C`, so it gets **the same address on
41+every EVM network**. The address derives from the salt and the creation code
42+only — not from the deployer account or its nonce.
43+
44+Check the address before spending gas:
45+
46+```shell
47+forge script script/Love.s.sol:LoveScript --sig 'predict()'
48+```
49+
50+Then deploy:
51+
38 ```shell52 ```shell
39 forge script script/Love.s.sol:LoveScript \53 forge script script/Love.s.sol:LoveScript \
40 --rpc-url base_sepolia \54 --rpc-url base_sepolia \
@@ -43,7 +57,27 @@ forge script script/Love.s.sol:LoveScript \
43 --verify57 --verify
44 ```58 ```
45 59
46-Drop `--broadcast` for a dry run.60+Drop `--broadcast` for a dry run. Re-running against a network where the token
61+already exists is a no-op.
62+
63+The salt defaults to `keccak256("LOVE")`; override it — to mine a vanity address,
64+say — with `SALT=0x… forge script …`. The same salt must be used on every
65+network.
66+
67+### Keeping the address stable
68+
69+The creation code, and therefore the address, changes if any of these change:
70+
71+- the contract source (`src/Love.sol`) or its OpenZeppelin version,
72+- `solc` (pinned to 0.8.30 in `foundry.toml`),
73+- optimizer settings (`optimizer = true`, `optimizer_runs = 200`, `via_ir = false`),
74+- `bytecode_hash` (set to `none`, which keeps the metadata hash out of the
75+ bytecode so paths and compiler metadata don't leak into the address).
76+
77+Treat those as frozen once the token is deployed anywhere.
78+
79+Chains lacking the deterministic deployer — zkSync-style chains in particular,
80+where CREATE2 addresses are computed differently — cannot match this address.
47 81
48 ## Layout82 ## Layout
49 83