// 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); } }