// SPDX-License-Identifier: MIT pragma solidity ^0.8.26; /// @title ROMANPAD — a coin launched against Rome /// @notice A fixed-supply ERC-20 whose quote side is an ancient Roman denomination. /// The pairing is written into the token itself and cannot be changed. contract RomanpadCoin { string public name; string public symbol; uint8 public constant decimals = 18; uint256 public totalSupply; /// @notice the Roman coin this token is paired with, e.g. "DENARIUS" string public romanCoin; /// @notice metal of the reference coin, e.g. "Silver" string public romanMetal; /// @notice opening ratio at launch: reference units per token, scaled by 1e18 uint256 public openingRatio; /// @notice who opened the market address public immutable creator; /// @notice block timestamp of the launch uint256 public immutable launchedAt; mapping(address => uint256) public balanceOf; mapping(address => mapping(address => uint256)) public allowance; event Transfer(address indexed from, address indexed to, uint256 value); event Approval(address indexed owner, address indexed spender, uint256 value); event Launched( address indexed creator, string romanCoin, string symbol, uint256 supply, uint256 openingRatio ); constructor( string memory _name, string memory _symbol, uint256 _supply, string memory _romanCoin, string memory _romanMetal, uint256 _openingRatio ) { name = _name; symbol = _symbol; romanCoin = _romanCoin; romanMetal = _romanMetal; openingRatio = _openingRatio; creator = msg.sender; launchedAt = block.timestamp; totalSupply = _supply; balanceOf[msg.sender] = _supply; emit Transfer(address(0), msg.sender, _supply); emit Launched(msg.sender, _romanCoin, _symbol, _supply, _openingRatio); } /// @notice human readable pair, e.g. "CAESAR / DENARIUS" function pair() external view returns (string memory) { return string(abi.encodePacked(symbol, " / ", romanCoin)); } function transfer(address to, uint256 value) external returns (bool) { _move(msg.sender, to, value); return true; } function approve(address spender, uint256 value) external returns (bool) { allowance[msg.sender][spender] = value; emit Approval(msg.sender, spender, value); return true; } function transferFrom(address from, address to, uint256 value) external returns (bool) { uint256 a = allowance[from][msg.sender]; if (a != type(uint256).max) { require(a >= value, "allowance"); allowance[from][msg.sender] = a - value; } _move(from, to, value); return true; } function _move(address from, address to, uint256 value) internal { require(to != address(0), "to zero"); uint256 b = balanceOf[from]; require(b >= value, "balance"); unchecked { balanceOf[from] = b - value; balanceOf[to] += value; } emit Transfer(from, to, value); } }