// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.27;
/// @notice Simple ERC20 token.
/// @author nani.eth (Nani DAO)
contract Token {
event Approval(address indexed from, address indexed to, uint amount);
event Transfer(address indexed from, address indexed to, uint amount);
event OwnershipTransferred(address indexed from, address indexed to);
error Unauthorized();
modifier onlyOwner {
if (msg.sender != owner) revert Unauthorized();
_;
}
string public constant name = "NANI";
string public constant symbol = unicode"⌘";
uint public constant decimals = 18;
uint public totalSupply;
address public owner = tx.origin;
mapping(address owner => uint) public balanceOf;
mapping(address owner => mapping(address spender => uint)) public allowance;
constructor() payable {}
function approve(address to, uint amount) public returns (bool) {
allowance[msg.sender][to] = amount;
emit Approval(msg.sender, to, amount);
return true;
}
function transfer(address to, uint amount) public returns (bool) {
balanceOf[msg.sender] -= amount;
unchecked { balanceOf[to] += amount; }
emit Transfer(msg.sender, to, amount);
return true;
}
function transferFrom(address from, address to, uint amount) public returns (bool) {
if (allowance[from][msg.sender] != type(uint).max)
allowance[from][msg.sender] -= amount;
balanceOf[from] -= amount;
unchecked { balanceOf[to] += amount; }
emit Transfer(from, to, amount);
return true;
}
// GOVERNANCE
function transferOwnership(address to) public onlyOwner {
emit OwnershipTransferred(msg.sender, owner = to);
}
function mint(address to, uint amount) public onlyOwner {
totalSupply += amount;
unchecked { balanceOf[to] += amount; }
emit Transfer(address(0), to, amount);
}
function burn(uint amount) public {
balanceOf[msg.sender] -= amount;
unchecked { totalSupply -= amount; }
emit Transfer(msg.sender, address(0), amount);
}
}
{
"compilationTarget": {
"src/Token.sol": "Token"
},
"evmVersion": "cancun",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 9999999
},
"remappings": [
":@forge/=lib/forge-std/src/",
":@solady/=lib/solady/"
]
}
[{"inputs":[],"stateMutability":"payable","type":"constructor"},{"inputs":[],"name":"Unauthorized","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]