erc20-vend

Create ERC20 tokens the can be minted by existing ERC20 token balance
Log | Files | Refs

GiftableToken.sol (5210B)


      1 pragma solidity >=0.8.0;
      2 
      3 // SPDX-License-Identifier: AGPL-3.0-or-later
      4 // File-Version: 3
      5 
      6 contract GiftableToken {
      7 
      8 	// Implements EIP173
      9 	address public owner;
     10 
     11 	// Implements Writer
     12 	mapping(address => bool) writer;
     13 
     14 	// Implements ERC20
     15 	string public name;
     16 	// Implements ERC20
     17 	string public symbol;
     18 	// Implements ERC20
     19 	uint8 public decimals;
     20 	// Implements ERC20
     21 	mapping (address => uint256) public balanceOf;
     22 	// Implements ERC20
     23 	mapping (address => mapping (address => uint256)) public allowance;
     24 
     25 	// Implements Burner
     26 	uint256 public totalMinted;
     27 	// Implements Burner
     28 	uint256 public totalBurned;
     29 
     30 	// Implements Expire
     31 	uint256 public expires;
     32 	bool expired;
     33 
     34 	// Implements ERC20
     35 	event Transfer(address indexed _from, address indexed _to, uint256 _value);
     36 	// Implements ERC20
     37 	event TransferFrom(address indexed _from, address indexed _to, address indexed _spender, uint256 _value);
     38 	// Implements ERC20
     39 	event Approval(address indexed _owner, address indexed _spender, uint256 _value);
     40 
     41 	// Implements Minter
     42 	event Mint(address indexed _minter, address indexed _beneficiary, uint256 _value);
     43 
     44 	// Implement Expire
     45 	event Expired(uint256 _timestamp);
     46 
     47 	// Implements Writer
     48 	event WriterAdded(address _writer);
     49 	// Implements Writer
     50 	event WriterRemoved(address _writer);
     51 
     52 	// Implements Burner
     53 	event Burn(uint256 _value);
     54 
     55 	constructor(string memory _name, string memory _symbol, uint8 _decimals, uint256 _expireTimestamp) {
     56 		owner = msg.sender;
     57 		name = _name;
     58 		symbol = _symbol;
     59 		decimals = _decimals;
     60 		expires = _expireTimestamp;
     61 	}
     62 
     63 	// Implements ERC20
     64 	function totalSupply() public view returns (uint256) {
     65 		return totalMinted - totalBurned;
     66 	}
     67 
     68 	// Implements Minter
     69 	mapping(address => bool) writers;
     70 	function mintTo(address _to, uint256 _value) public returns (bool) {
     71 		require(writers[msg.sender] || msg.sender == owner);
     72 
     73 		balanceOf[_to] += _value;
     74 		totalMinted += _value;
     75 
     76 		emit Mint(msg.sender, _to, _value);
     77 
     78 		return true;
     79 	}
     80 
     81 	// Implements Minter
     82 	// Implements ERC5679Ext20
     83 	function mint(address _to, uint256 _value, bytes calldata _data) public {
     84 		_data;
     85 		mintTo(_to, _value);
     86 	}
     87 
     88 	// Implements Writer
     89 	function addWriter(address _minter) public returns (bool) {
     90 		require(msg.sender == owner);
     91 
     92 		writers[_minter] = true;
     93 
     94 		return true;
     95 	}
     96 
     97 	// Implements Writer
     98 	function deleteWriter(address _minter) public returns (bool) {
     99 		require(msg.sender == owner || msg.sender == _minter);
    100 
    101 		writers[_minter] = false;
    102 
    103 		return true;
    104 	}
    105 
    106 	// Implements Writer
    107 	function isWriter(address _minter) public view returns(bool) {
    108 		return writers[_minter] || _minter == owner;
    109 	}
    110 
    111 	// Implements Expire
    112 	function applyExpiry() public returns(uint8) {
    113 		if (expires == 0) {
    114 			return 0;
    115 		}
    116 		if (expired) {
    117 			return 1;
    118 		}
    119 		if (block.timestamp >= expires) {
    120 			expired = true;
    121 			emit Expired(block.timestamp);
    122 			return 2;
    123 		}
    124 		return 0;
    125 
    126 	}
    127 
    128 	// Implements ERC20
    129 	function transfer(address _to, uint256 _value) public returns (bool) {
    130 		require(applyExpiry() == 0);
    131 		require(balanceOf[msg.sender] >= _value);
    132 		balanceOf[msg.sender] -= _value; 
    133 		balanceOf[_to] += _value;
    134 		emit Transfer(msg.sender, _to, _value);
    135 		return true;
    136 	}
    137 
    138 	// Implements Burner
    139 	function burn(uint256 _value) public returns (bool) {
    140 		require(msg.sender == owner, 'ERR_ACCESS');
    141 		require(balanceOf[msg.sender] >= _value, 'ERR_FUNDS');
    142 
    143 		balanceOf[msg.sender] -= _value;
    144 		totalBurned += _value;
    145 
    146 		emit Burn(_value);
    147 		return true;
    148 	}
    149 
    150 	// Implements Burner
    151 	function burn() public returns(bool) {
    152 		return burn(balanceOf[msg.sender]);
    153 	}
    154 
    155 	// Implements Burner
    156 	// Implements ERC5679Ext20
    157 	function burn(address _from, uint256 _value, bytes calldata _data) public {
    158 		require(msg.sender == _from, 'ERR_NOT_SELF');
    159 		_data;
    160 		burn(_value);
    161 	}
    162 
    163 	// Implements ERC20
    164 	function transferFrom(address _from, address _to, uint256 _value) public returns (bool) {
    165 		require(applyExpiry() == 0);
    166 		require(allowance[_from][msg.sender] >= _value);
    167 		require(balanceOf[_from] >= _value);
    168 		allowance[_from][msg.sender] = allowance[_from][msg.sender] - _value;
    169 		balanceOf[_from] -= _value; 
    170 		balanceOf[_to] += _value;
    171 		emit TransferFrom(_from, _to, msg.sender, _value);
    172 		return true;
    173 	}
    174 
    175 	// Implements ERC20
    176 	function approve(address _spender, uint256 _value) public returns (bool) {
    177 		require(applyExpiry() == 0);
    178 		if (_value > 0) {
    179 			require(allowance[msg.sender][_spender] == 0);
    180 		}
    181 		allowance[msg.sender][_spender] = _value;
    182 		emit Approval(msg.sender, _spender, _value);
    183 		return true;
    184 	}
    185 
    186 	// Implements EIP173
    187 	function transferOwnership(address _newOwner) public returns (bool) {
    188 		require(msg.sender == owner);
    189 		owner = _newOwner;
    190 		return true;
    191 	}
    192 
    193 	// Implements EIP165
    194 	function supportsInterface(bytes4 _sum) public pure returns (bool) {
    195 		if (_sum == 0xb61bc941) { // ERC20
    196 			return true;
    197 		}
    198 		if (_sum == 0x449a52f8) { // Minter
    199 			return true;
    200 		}
    201 		if (_sum == 0x01ffc9a7) { // EIP165
    202 			return true;
    203 		}
    204 		if (_sum == 0x9493f8b2) { // EIP173
    205 			return true;
    206 		}
    207 		if (_sum == 0xabe1f1f5) { // Writer
    208 			return true;
    209 		}
    210 		if (_sum == 0xb1110c1b) { // Burner
    211 			return true;
    212 		}
    213 		if (_sum == 0x841a0e94) { // Expire
    214 			return true;
    215 		}
    216 		return false;
    217 	}
    218 }