/* Copyright 2021 DODO ZOO. SPDX-License-Identifier: Apache-2.0 */ pragma solidity 0.6.9; import {SafeMath} from "../../lib/SafeMath.sol"; import {InitializableOwnable} from "../../lib/InitializableOwnable.sol"; contract InitializableInternalMintableERC20 is InitializableOwnable { using SafeMath for uint256; string public name; uint8 public decimals; string public symbol; uint256 public totalSupply; mapping(address => uint256) internal balances; mapping(address => mapping(address => uint256)) internal allowed; event Transfer(address indexed from, address indexed to, uint256 amount); event Approval(address indexed owner, address indexed spender, uint256 amount); event Mint(address indexed user, uint256 value); event Burn(address indexed user, uint256 value); function init( address _creator, uint256 _initSupply, string memory _name, string memory _symbol, uint8 _decimals ) public { initOwner(_creator); name = _name; symbol = _symbol; decimals = _decimals; totalSupply = _initSupply; balances[_creator] = _initSupply; emit Transfer(address(0), _creator, _initSupply); } function transfer(address to, uint256 amount) public virtual returns (bool) { require(to != address(0), "TO_ADDRESS_IS_EMPTY"); require(amount <= balances[msg.sender], "BALANCE_NOT_ENOUGH"); balances[msg.sender] = balances[msg.sender].sub(amount); balances[to] = balances[to].add(amount); emit Transfer(msg.sender, to, amount); return true; } function balanceOf(address owner) public view returns (uint256 balance) { return balances[owner]; } function transferFrom( address from, address to, uint256 amount ) public virtual returns (bool) { require(to != address(0), "TO_ADDRESS_IS_EMPTY"); require(amount <= balances[from], "BALANCE_NOT_ENOUGH"); require(amount <= allowed[from][msg.sender], "ALLOWANCE_NOT_ENOUGH"); balances[from] = balances[from].sub(amount); balances[to] = balances[to].add(amount); allowed[from][msg.sender] = allowed[from][msg.sender].sub(amount); emit Transfer(from, to, amount); return true; } function approve(address spender, uint256 amount) public virtual returns (bool) { allowed[msg.sender][spender] = amount; emit Approval(msg.sender, spender, amount); return true; } function allowance(address owner, address spender) public view returns (uint256) { return allowed[owner][spender]; } function _mint(address user, uint256 value) internal { balances[user] = balances[user].add(value); totalSupply = totalSupply.add(value); emit Mint(user, value); emit Transfer(address(0), user, value); } function _burn(address user, uint256 value) internal { balances[user] = balances[user].sub(value); totalSupply = totalSupply.sub(value); emit Burn(user, value); emit Transfer(user, address(0), value); } }