TokenTemplate
The ERC-20 every LP24 token runs. Standard interface plus a minter-only mint/burn and a transfer lock that lifts at graduation.
Minimal proxy (EIP-1167). Initialized once by the factory. 9 decimals. No owner, no blacklist, no pause, no fee-on-transfer.
Transfer States
| State | Value | Transfers |
|---|---|---|
STATE_UNINITIALIZED | 0 | — |
STATE_LOCKED | 1 | Only the minter (the bonding curve) can move tokens |
STATE_TRADING | 2 | Open to everyone |
transferFrom is slightly more permissive while locked: it also allows transfers to the minter, so selling back to the curve works before graduation.
ERC-20 Interface
| Function | Notes |
|---|---|
transfer(to, amount) -> bool | Reverts "Trading not enabled" while locked |
transferFrom(from, to, amount) -> bool | Same, unless one side is the minter |
approve(spender, amount) -> bool | Allowed in any state |
increaseAllowance(spender, added) -> bool | Checked arithmetic — reverts on overflow |
decreaseAllowance(spender, subtracted) -> bool | Reverts "Decreased allowance below zero" |
balanceOf(addr) -> uint256 | Public mapping |
allowance(owner, spender) -> uint256 | Public nested mapping |
totalSupply() -> uint256 | Rises with mints, falls with burns |
name() / symbol() / decimals() | 9 decimals, fixed |
Mint and Burn
mint(to: address, amount: uint256) externalMinter only. The minter is the bonding curve, set at initialization and never changeable. Enforces the 1,200,000,000 × 10⁹ (1.2B) hard cap.
"Only minter""Mint to zero address""Exceeds max supply"
burnFrom(from_addr: address, amount: uint256) externalMinter only. Used by the curve on sells and refund claims. Does not consume allowance — the curve verifies the balance itself.
"Only minter""Burn from zero address""Burn exceeds balance"
Only the bonding curve. It mints on buys and, once, the 400,000,000 × 10⁹ (400M) liquidity allocation at graduation. After graduation the curve is closed to trading, so the only remaining supply changes are burns — from secondary-pool fees, buy-and-burn, and dust cleanup. Supply is monotonically non-increasing from graduation onward.
Graduation
enableTrading() externalMinter only. Moves STATE_LOCKED → STATE_TRADING, permanently. Called inside graduation.
"Only minter","Invalid state"
TradingEnabled(timestamp)
Initialization
initialize(_name, _symbol, _minter, _deployer, _mint_to) externalFactory only. Mints 60,000,000 × 10⁹ (60M) to _mint_to — the deployer on the user path, the vesting contract on the protocol path. _deployer is stored separately for authorization.
"Already initialized""Invalid minter"/"Invalid deployer"/"Invalid mint recipient""Unauthorized"
Views
| Function | Returns |
|---|---|
tradingEnabled() -> bool | Whether transfers are open |
minter() -> address | The bonding curve |
deployer() -> address | Original deployer at launch. Not updated by CTO — the authoritative current deployer is PrimaryHook.tokenInfo(token).deployer. |
Constants
| Constant | Value |
|---|---|
decimals | 9 |
INITIAL_MINT_AMOUNT | 60,000,000 × 10⁹ (60M) |
MAX_SUPPLY | 1,200,000,000 × 10⁹ (1.2B) |