trim readme
1a71b77 parent: 1c407d3 modified
README.md +18 -61 | @@ -1,55 +1,31 @@ | ||
| 1 | -# love | |
| 1 | +# Love | |
| 2 | 2 | |
| 3 | -A [Foundry](https://getfoundry.sh) project. | |
| 3 | +The official LOVE token. | |
| 4 | 4 | |
| 5 | -`Love` (`LOVE`, 18 decimals) is a basic ERC-20 built on | |
| 6 | -[OpenZeppelin](https://github.com/OpenZeppelin/openzeppelin-contracts), with one | |
| 7 | -deliberate twist: `mint` has **no access control**. | |
| 8 | - | |
| 9 | -```solidity | |
| 10 | -function mint(address to, uint256 amount) external; | |
| 11 | -``` | |
| 12 | - | |
| 13 | -Anyone can mint any amount to any address. Supply starts at zero and is | |
| 14 | -unbounded, so the token carries no economic value — it is a faucet / demo token. | |
| 15 | -Do not deploy it to mainnet expecting otherwise. | |
| 16 | - | |
| 17 | -## Setup | |
| 5 | +## Install | |
| 18 | 6 | |
| 19 | 7 | ```shell |
| 20 | 8 | forge install |
| 21 | 9 | cp .env.example .env |
| 22 | 10 | ``` |
| 23 | 11 | |
| 24 | -## Usage | |
| 12 | +## Build & test | |
| 25 | 13 | |
| 26 | 14 | ```shell |
| 27 | 15 | forge build # compile |
| 28 | 16 | forge test # run tests |
| 29 | 17 | forge test -vvv # with traces |
| 30 | 18 | forge fmt # format |
| 31 | -forge coverage # coverage report | |
| 32 | -forge snapshot # gas snapshot | |
| 33 | 19 | anvil # local node |
| 34 | 20 | ``` |
| 35 | 21 | |
| 36 | 22 | ## Deploy |
| 37 | 23 | |
| 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: | |
| 24 | +Deployment uses CREATE2, so the token has the same address on every EVM network. | |
| 45 | 25 | |
| 46 | 26 | ```shell |
| 47 | -forge script script/Love.s.sol:LoveScript --sig 'predict()' | |
| 48 | -``` | |
| 27 | +forge script script/Love.s.sol:LoveScript --sig 'predict()' # print the address | |
| 49 | 28 | |
| 50 | -Then deploy: | |
| 51 | - | |
| 52 | -```shell | |
| 53 | 29 | forge script script/Love.s.sol:LoveScript \ |
| 54 | 30 | --rpc-url base_sepolia \ |
| 55 | 31 | --account "$DEPLOYER_ACCOUNT" \ |
| @@ -57,37 +33,6 @@ forge script script/Love.s.sol:LoveScript \ | ||
| 57 | 33 | --verify |
| 58 | 34 | ``` |
| 59 | 35 | |
| 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. | |
| 81 | - | |
| 82 | -## Layout | |
| 83 | - | |
| 84 | -| Path | Contents | | |
| 85 | -| --------- | ------------------- | | |
| 86 | -| `src/` | Contracts | | |
| 87 | -| `test/` | Tests | | |
| 88 | -| `script/` | Deployment scripts | | |
| 89 | -| `lib/` | Dependencies | | |
| 90 | - | |
| 91 | 36 | ## Mint |
| 92 | 37 | |
| 93 | 38 | ```shell |
| @@ -95,3 +40,15 @@ cast send <LOVE_ADDRESS> "mint(address,uint256)" <RECIPIENT> 1000000000000000000 | ||
| 95 | 40 | --rpc-url base_sepolia \ |
| 96 | 41 | --account "$DEPLOYER_ACCOUNT" |
| 97 | 42 | ``` |
| 43 | + | |
| 44 | +## License | |
| 45 | + | |
| 46 | +GPL-3.0 | |
| 47 | + | |
| 48 | +## Contact | |
| 49 | + | |
| 50 | +**Julien Béranger** ([GitHub](https://github.com/julienbrg)) | |
| 51 | + | |
| 52 | +- Element: [@julienbrg:matrix.org](https://matrix.to/#/@julienbrg:matrix.org) | |
| 53 | +- Farcaster: [julien-](https://warpcast.com/julien-) | |
| 54 | +- Telegram: [@julienbrg](https://t.me/julienbrg) | |
| @@ -1,55 +1,31 @@ | |||
| 1 | -# love | 1 | +# Love |
| 2 | 2 | ||
| 3 | -A [Foundry](https://getfoundry.sh) project. | 3 | +The official LOVE token. |
| 4 | 4 | ||
| 5 | -`Love` (`LOVE`, 18 decimals) is a basic ERC-20 built on | 5 | +## Install |
| 6 | -[OpenZeppelin](https://github.com/OpenZeppelin/openzeppelin-contracts), with one | ||
| 7 | -deliberate twist: `mint` has **no access control**. | ||
| 8 | - | ||
| 9 | -```solidity | ||
| 10 | -function mint(address to, uint256 amount) external; | ||
| 11 | -``` | ||
| 12 | - | ||
| 13 | -Anyone can mint any amount to any address. Supply starts at zero and is | ||
| 14 | -unbounded, so the token carries no economic value — it is a faucet / demo token. | ||
| 15 | -Do not deploy it to mainnet expecting otherwise. | ||
| 16 | - | ||
| 17 | -## Setup | ||
| 18 | 6 | ||
| 19 | ```shell | 7 | ```shell |
| 20 | forge install | 8 | forge install |
| 21 | cp .env.example .env | 9 | cp .env.example .env |
| 22 | ``` | 10 | ``` |
| 23 | 11 | ||
| 24 | -## Usage | 12 | +## Build & test |
| 25 | 13 | ||
| 26 | ```shell | 14 | ```shell |
| 27 | forge build # compile | 15 | forge build # compile |
| 28 | forge test # run tests | 16 | forge test # run tests |
| 29 | forge test -vvv # with traces | 17 | forge test -vvv # with traces |
| 30 | forge fmt # format | 18 | forge fmt # format |
| 31 | -forge coverage # coverage report | ||
| 32 | -forge snapshot # gas snapshot | ||
| 33 | anvil # local node | 19 | anvil # local node |
| 34 | ``` | 20 | ``` |
| 35 | 21 | ||
| 36 | ## Deploy | 22 | ## Deploy |
| 37 | 23 | ||
| 38 | -`Love` is deployed with CREATE2 through the canonical | 24 | +Deployment uses CREATE2, so the token has the same address on every EVM network. |
| 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 | 25 | ||
| 46 | ```shell | 26 | ```shell |
| 47 | -forge script script/Love.s.sol:LoveScript --sig 'predict()' | 27 | +forge script script/Love.s.sol:LoveScript --sig 'predict()' # print the address |
| 48 | -``` | ||
| 49 | 28 | ||
| 50 | -Then deploy: | ||
| 51 | - | ||
| 52 | -```shell | ||
| 53 | forge script script/Love.s.sol:LoveScript \ | 29 | forge script script/Love.s.sol:LoveScript \ |
| 54 | --rpc-url base_sepolia \ | 30 | --rpc-url base_sepolia \ |
| 55 | --account "$DEPLOYER_ACCOUNT" \ | 31 | --account "$DEPLOYER_ACCOUNT" \ |
| @@ -57,37 +33,6 @@ forge script script/Love.s.sol:LoveScript \ | |||
| 57 | --verify | 33 | --verify |
| 58 | ``` | 34 | ``` |
| 59 | 35 | ||
| 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. | ||
| 81 | - | ||
| 82 | -## Layout | ||
| 83 | - | ||
| 84 | -| Path | Contents | | ||
| 85 | -| --------- | ------------------- | | ||
| 86 | -| `src/` | Contracts | | ||
| 87 | -| `test/` | Tests | | ||
| 88 | -| `script/` | Deployment scripts | | ||
| 89 | -| `lib/` | Dependencies | | ||
| 90 | - | ||
| 91 | ## Mint | 36 | ## Mint |
| 92 | 37 | ||
| 93 | ```shell | 38 | ```shell |
| @@ -95,3 +40,15 @@ cast send <LOVE_ADDRESS> "mint(address,uint256)" <RECIPIENT> 1000000000000000000 | |||
| 95 | --rpc-url base_sepolia \ | 40 | --rpc-url base_sepolia \ |
| 96 | --account "$DEPLOYER_ACCOUNT" | 41 | --account "$DEPLOYER_ACCOUNT" |
| 97 | ``` | 42 | ``` |
| 43 | + | ||
| 44 | +## License | ||
| 45 | + | ||
| 46 | +GPL-3.0 | ||
| 47 | + | ||
| 48 | +## Contact | ||
| 49 | + | ||
| 50 | +**Julien Béranger** ([GitHub](https://github.com/julienbrg)) | ||
| 51 | + | ||
| 52 | +- Element: [@julienbrg:matrix.org](https://matrix.to/#/@julienbrg:matrix.org) | ||
| 53 | +- Farcaster: [julien-](https://warpcast.com/julien-) | ||
| 54 | +- Telegram: [@julienbrg](https://t.me/julienbrg) | ||