julien/lovepublic Fork 0
5376202c13fb4103a21f603fecc7fd40680b607b
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.

add weth peg tests and docs 5376202 · on 5376202c13fb4103a21f603fecc7fd40680b607b · julienbrg · 8h ago
Love.s.sol · 88 lines · 3.3 KBSolidity Blame HistoryRaw
 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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;

import {Love} from "../src/Love.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {Script, console} from "forge-std/Script.sol";

/// @notice Deploys `Love` with CREATE2 through the canonical deterministic
///         deployer. The address depends on the salt and the creation code, and
///         the creation code embeds the wETH address — so the token only gets
///         the same address on chains where wETH sits at the same address. Keep
///         `solc`, the optimizer settings and `bytecode_hash = "none"` as they
///         are in `foundry.toml`, or the address changes too.
contract LoveScript is Script {
    bytes32 public constant DEFAULT_SALT = keccak256("LOVE");

    /// @dev wETH on Base, Optimism and every other OP-Stack chain.
    address public constant DEFAULT_WETH = 0x4200000000000000000000000000000000000006;

    Love public love;

    function run() public returns (Love) {
        bytes32 s = salt();
        address w = wethAddress();
        address predicted = predict(s, w);

        console.log("deployer     ", CREATE2_FACTORY);
        console.log("salt         ", vm.toString(s));
        console.log("weth         ", w);
        console.log("initCodeHash ", vm.toString(initCodeHash(w)));
        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}(IERC20(w));
        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("weth         ", address(love.WETH()));
        console.log("rate         ", love.RATE());
        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();
        address w = wethAddress();
        predicted = predict(s, w);

        console.log("salt         ", vm.toString(s));
        console.log("weth         ", w);
        console.log("initCodeHash ", vm.toString(initCodeHash(w)));
        console.log("predicted    ", predicted);
    }

    function predict(bytes32 s, address w) public pure returns (address) {
        return vm.computeCreate2Address(s, initCodeHash(w), CREATE2_FACTORY);
    }

    function initCode(address w) public pure returns (bytes memory) {
        return abi.encodePacked(type(Love).creationCode, abi.encode(w));
    }

    function initCodeHash(address w) public pure returns (bytes32) {
        return keccak256(initCode(w));
    }

    /// @dev `SALT` overrides the default, e.g. to mine a vanity address.
    function salt() public view returns (bytes32) {
        return vm.envOr("SALT", DEFAULT_SALT);
    }

    /// @dev `WETH` overrides the default, which only holds on OP-Stack chains.
    function wethAddress() public view returns (address) {
        return vm.envOr("WETH", DEFAULT_WETH);
    }
}