// SPDX-License-Identifier: MIT pragma solidity 0.8.0; import "@0xcert/ethereum-utils-contracts/src/contracts/utils/supports-interface.sol"; import "./erc20.sol"; /** * @title ERC20 standard token implementation. * @dev This interface uses the official ERC-20 specification from * https://eips.ethereum.org/EIPS/eip-20 and also implements every optional * function. */ contract Token is ERC20, SupportsInterface { /** * @dev Error constants. */ string constant NOT_ENOUGH_BALANCE = "001001"; string constant NOT_ENOUGH_ALLOWANCE = "001002"; /** * @dev Token name. */ string internal tokenName; /** * @dev Token symbol. */ string internal tokenSymbol; /** * @dev Number of decimals. */ uint8 internal tokenDecimals; /** * @dev Total supply of tokens. */ uint256 internal tokenTotalSupply; /** * @dev Balance information map. */ mapping (address => uint256) internal balances; /** * @dev Token allowance mapping. */ mapping (address => mapping (address => uint256)) internal allowed; /** * @dev Contract constructor. */ constructor() { supportedInterfaces[0x36372b07] = true; // ERC20 supportedInterfaces[0x06fdde03] = true; // ERC20 name supportedInterfaces[0x95d89b41] = true; // ERC20 symbol supportedInterfaces[0x313ce567] = true; // ERC20 decimals } /** * @dev Returns the name of the token. */ function name() external override view returns (string memory _name) { _name = tokenName; } /** * @dev Returns the symbol of the token. */ function symbol() external override view returns (string memory _symbol) { _symbol = tokenSymbol; } /** * @dev Returns the number of decimals the token uses. */ function decimals() external override view returns (uint8 _decimals) { _decimals = tokenDecimals; } /** * @dev Returns the total token supply. */ function totalSupply() external override view returns (uint256 _totalSupply) { _totalSupply = tokenTotalSupply; } /** * @dev Returns the account balance of another account with address _owner. * @param _owner The address from which the balance will be retrieved. */ function balanceOf( address _owner ) external override view returns (uint256 _balance) { _balance = balances[_owner]; } /** * @dev Returns the amount which _spender is still allowed to withdraw from _owner. * @param _owner The address of the account owning tokens. * @param _spender The address of the account able to transfer the tokens. */ function allowance( address _owner, address _spender ) external override view returns (uint256 _remaining) { _remaining = allowed[_owner][_spender]; } /** * @dev Transfers _value amount of tokens to address _to, and MUST fire the Transfer event. The * function SHOULD throw if the message caller's account balance does not have enough tokens to * spend. * @param _to The address of the recipient. * @param _value The amount of token to be transferred. */ function transfer( address _to, uint256 _value ) public override returns (bool _success) { require(_value <= balances[msg.sender], NOT_ENOUGH_BALANCE); balances[msg.sender] = balances[msg.sender] - _value; balances[_to] = balances[_to] + _value; emit Transfer(msg.sender, _to, _value); _success = true; } /** * @dev Allows _spender to withdraw from your account multiple times, up to the _value amount. If * this function is called again it overwrites the current allowance with _value. * To prevent attack vectors like the one described here: * https://docs.google.com/document/d/1YLPtQxZu1UAvO9cZ1O2RPXBbT0mooh4DYKjA_jp-RLM/edit and * discussed here: https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729, clients * SHOULD make sure to create user interfaces in such a way that they set the allowance first to 0 * before setting it to another value for the same spender. THOUGH The contract itself shouldn’t * enforce it, to allow backwards compatibility with contracts deployed before. * @param _spender The address of the account able to transfer the tokens. * @param _value The amount of tokens to be approved for transfer. */ function approve( address _spender, uint256 _value ) public override returns (bool _success) { allowed[msg.sender][_spender] = _value; emit Approval(msg.sender, _spender, _value); _success = true; } /** * @dev Transfers _value amount of tokens from address _from to address _to, and MUST fire the * Transfer event. * @param _from The address of the sender. * @param _to The address of the recipient. * @param _value The amount of token to be transferred. */ function transferFrom( address _from, address _to, uint256 _value ) public override returns (bool _success) { require(_value <= balances[_from], NOT_ENOUGH_BALANCE); require(_value <= allowed[_from][msg.sender], NOT_ENOUGH_ALLOWANCE); balances[_from] = balances[_from] - _value; balances[_to] = balances[_to] + _value; allowed[_from][msg.sender] = allowed[_from][msg.sender] - _value; emit Transfer(_from, _to, _value); _success = true; } }