love
A Foundry project.
Love (LOVE, 18 decimals) is a basic ERC-20 built on
OpenZeppelin, with one
deliberate twist: mint has no access control.
function mint(address to, uint256 amount) external;
Anyone can mint any amount to any address. Supply starts at zero and is
unbounded, so the token carries no economic value — it is a faucet / demo token.
Do not deploy it to mainnet expecting otherwise.
Setup
forge install
cp .env.example .env
Usage
forge build # compile
forge test # run tests
forge test -vvv # with traces
forge fmt # format
forge coverage # coverage report
forge snapshot # gas snapshot
anvil # local node
Deploy
Love is deployed with CREATE2 through the canonical
deterministic deployer
at 0x4e59b44847b379578588920cA78FbF26c0B4956C, so it gets the same address on
every EVM network. The address derives from the salt and the creation code
only — not from the deployer account or its nonce.
Check the address before spending gas:
forge script script/Love.s.sol:LoveScript --sig 'predict()'
Then deploy:
forge script script/Love.s.sol:LoveScript \
--rpc-url base_sepolia \
--account "$DEPLOYER_ACCOUNT" \
--broadcast \
--verify
Drop --broadcast for a dry run. Re-running against a network where the token
already exists is a no-op.
The salt defaults to keccak256("LOVE"); override it — to mine a vanity address,
say — with SALT=0x… forge script …. The same salt must be used on every
network.
Keeping the address stable
The creation code, and therefore the address, changes if any of these change:
- the contract source (
src/Love.sol) or its OpenZeppelin version, solc(pinned to 0.8.30 infoundry.toml),- optimizer settings (
optimizer = true,optimizer_runs = 200,via_ir = false), bytecode_hash(set tonone, which keeps the metadata hash out of the
bytecode so paths and compiler metadata don't leak into the address).
Treat those as frozen once the token is deployed anywhere.
Chains lacking the deterministic deployer — zkSync-style chains in particular,
where CREATE2 addresses are computed differently — cannot match this address.
Layout
| Path | Contents |
|---|---|
src/ |
Contracts |
test/ |
Tests |
script/ |
Deployment scripts |
lib/ |
Dependencies |
Mint
cast send <LOVE_ADDRESS> "mint(address,uint256)" <RECIPIENT> 1000000000000000000 \
--rpc-url base_sepolia \
--account "$DEPLOYER_ACCOUNT"
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 89 90 91 92 93 94 95 96 97 |
|