Created
November 4, 2024 03:44
-
-
Save darkerego/faf6972e61c10fa22bbb19af23ab9abc to your computer and use it in GitHub Desktop.
A minimalist ERC20 token size optimized for low deployment costs.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// SPDX-License-Identifier: MIT | |
pragma solidity ^0.8.18; | |
abstract contract MinimalistErc20 { | |
address public owner; | |
string public name; | |
string public symbol; | |
uint256 public totalSupply; | |
uint8 immutable public decimals; | |
mapping (address => uint256) public balanceOf; | |
mapping (address => mapping (address => uint256)) public allowances; | |
event Transfer(address indexed from, address indexed to, uint256 amount); | |
event Approval(address indexed _account, address indexed spender, uint indexed amount); | |
/* | |
@dev custom error function are cheaper than require statements | |
*/ | |
error InsufficientBalance(address, uint256); | |
error InsufficientAllowance(address, address, uint256); | |
error Unauthorized(); | |
error UseBurn(); | |
constructor(string memory _symbol, string memory _name){ | |
symbol = _symbol; | |
name = _name; | |
decimals = 18; | |
owner = msg.sender; | |
} | |
function _transfer(address _from, address _to, uint256 _amount) internal returns(bool) { | |
if (_from == address(0) && _to != address(0)) { | |
// Mint tokens | |
totalSupply += _amount; | |
balanceOf[_to] += _amount; | |
emit Transfer(_from, _to, _amount); | |
return true; | |
} | |
else if (_to == address(0) && _from != address(0)) { | |
// Burn tokens | |
if (balanceOf[_from] < _amount) { | |
revert InsufficientBalance(_from, _amount); | |
} | |
totalSupply -= _amount; | |
balanceOf[_from] -= _amount; | |
emit Transfer(_from, _to, _amount); | |
return true; | |
} | |
else { | |
// Regular transfer | |
if (balanceOf[_from] < _amount) { | |
revert InsufficientBalance(_from, _amount); | |
} | |
balanceOf[_from] -= _amount; | |
balanceOf[_to] += _amount; | |
emit Transfer(_from, _to, _amount); | |
return true; | |
} | |
} | |
function burn(uint amount) external returns(bool) { | |
return _transfer(msg.sender, address(0), amount); | |
} | |
function mint(uint256 _amount, address _to) public returns(bool) { | |
if (msg.sender != owner) { | |
revert Unauthorized(); | |
} | |
_transfer(address(0), _to, _amount); | |
return true; | |
} | |
function approve(address _spender, uint256 _amount) external returns(bool) { | |
allowances[msg.sender][_spender] = _amount; | |
emit Approval(msg.sender, _spender, _amount); | |
return true; | |
} | |
function increaseAllowance(address _spender, uint256 addedValue) external returns(bool) { | |
allowances[msg.sender][_spender] += addedValue; | |
emit Approval(msg.sender, _spender, allowances[msg.sender][_spender]); | |
return true; | |
} | |
function decreaseAllowance(address _spender, uint256 subtractedValue) external returns(bool) { | |
uint256 currentAllowance = allowances[msg.sender][_spender]; | |
if (subtractedValue > currentAllowance) { | |
revert InsufficientAllowance(msg.sender, _spender, subtractedValue); | |
} | |
allowances[msg.sender][_spender] -= subtractedValue; | |
emit Approval(msg.sender, _spender, allowances[msg.sender][_spender]); | |
return true; | |
} | |
function transfer(address to, uint256 amount) external returns(bool) { | |
if (to == address(0)) { | |
revert UseBurn(); | |
} | |
_transfer(msg.sender, to, amount); | |
return true; | |
} | |
function transferFrom(address from, address to, uint256 amount) external returns(bool) { | |
if (to == address(0)) { | |
revert UseBurn(); | |
} | |
if (allowances[from][msg.sender] < amount) { | |
revert InsufficientAllowance(from, to, amount); | |
} | |
// Deduct the allowance | |
allowances[from][msg.sender] -= amount; | |
return _transfer(from, to, amount); | |
} | |
function renounceOwnership() external returns(bool) { | |
if (msg.sender == owner) { | |
owner = address(0); | |
return true; | |
} else { | |
revert Unauthorized(); | |
} | |
} | |
} | |
contract TestToken is MinimalistErc20 { | |
constructor() MinimalistErc20("Test", "T") { | |
mint(1000000 * 10**decimals, msg.sender); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment