// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import {ERC20Burnable} from "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol"; import {ERC20Permit} from "@openzeppelin/contracts/token/ERC20/extensions/ERC20Permit.sol"; /** * @title SatelliteToken * @notice Fixed-supply ERC-20 deployed by SatelliteLaunchPad directly from the * creator's wallet. Built only from audited OpenZeppelin v5 components. * * - The entire supply is minted once, to the deployer, in the constructor. * - There is no owner, no mint function, no pause, no blacklist, no fee switch. * - Holders can burn their own tokens (ERC20Burnable). * - Gasless approvals are supported via EIP-2612 permit (ERC20Permit). * - Project metadata (website / description) is stored on-chain, immutable. */ contract SatelliteToken is ERC20, ERC20Burnable, ERC20Permit { /// @notice Project website supplied at launch (may be empty). string public website; /// @notice Short project description supplied at launch (may be empty). string public description; /// @notice The platform that produced this deployment. string public constant LAUNCHPAD = "SatelliteLaunchPad"; /** * @param name_ Token name, e.g. "SatelliteLaunchPad" * @param symbol_ Token symbol, e.g. "STPAD" * @param supply_ Whole-token supply (18 decimals are added here) * @param website_ Optional website URL * @param description_ Optional description */ constructor( string memory name_, string memory symbol_, uint256 supply_, string memory website_, string memory description_ ) ERC20(name_, symbol_) ERC20Permit(name_) { require(bytes(name_).length > 0, "SatelliteToken: empty name"); require(bytes(symbol_).length > 0, "SatelliteToken: empty symbol"); require(supply_ > 0, "SatelliteToken: zero supply"); website = website_; description = description_; _mint(msg.sender, supply_ * 10 ** decimals()); } }