1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
|
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;
import {Love} from "../src/Love.sol";
import {Script, console} from "forge-std/Script.sol";
/// @notice Deploys `Love` with CREATE2 through the canonical deterministic
/// deployer, so the token gets the same address on every EVM network.
/// The address depends only on the salt and the creation code — keep
/// `solc`, the optimizer settings and `bytecode_hash = "none"` as they
/// are in `foundry.toml`, or the address changes.
contract LoveScript is Script {
bytes32 public constant DEFAULT_SALT = keccak256("LOVE");
Love public love;
function run() public returns (Love) {
bytes32 s = salt();
address predicted = predict(s);
console.log("deployer ", CREATE2_FACTORY);
console.log("salt ", vm.toString(s));
console.log("initCodeHash ", vm.toString(initCodeHash()));
console.log("predicted ", predicted);
if (predicted.code.length > 0) {
console.log("already deployed, nothing to do");
love = Love(predicted);
return love;
}
vm.startBroadcast();
love = new Love{salt: s}();
vm.stopBroadcast();
require(address(love) == predicted, "LoveScript: address mismatch");
console.log("Love deployed at", address(love));
console.log("name ", love.name());
console.log("symbol ", love.symbol());
console.log("totalSupply ", love.totalSupply());
return love;
}
/// @notice Print the address `run()` would deploy to, without broadcasting.
function predict() public view returns (address predicted) {
bytes32 s = salt();
predicted = predict(s);
console.log("salt ", vm.toString(s));
console.log("initCodeHash ", vm.toString(initCodeHash()));
console.log("predicted ", predicted);
}
function predict(bytes32 s) public pure returns (address) {
return vm.computeCreate2Address(s, initCodeHash(), CREATE2_FACTORY);
}
function initCodeHash() public pure returns (bytes32) {
return keccak256(type(Love).creationCode);
}
/// @dev `SALT` overrides the default, e.g. to mine a vanity address.
function salt() public view returns (bytes32) {
return vm.envOr("SALT", DEFAULT_SALT);
}
}
|