eth-erc20/solidity/GiftableToken.sol

219 lines
5.1 KiB
Solidity
Raw Normal View History

2023-03-26 09:07:41 +02:00
pragma solidity >=0.8.0;
2023-03-26 09:07:41 +02:00
// SPDX-License-Identifier: AGPL-3.0-or-later
// File-Version: 3
contract GiftableToken {
2023-02-22 11:48:32 +01:00
// Implements EIP173
2021-12-09 06:23:21 +01:00
address public owner;
2023-02-22 11:48:32 +01:00
// Implements Writer
mapping(address => bool) writer;
2021-05-02 16:33:00 +02:00
// Implements ERC20
string public name;
2021-05-02 16:33:00 +02:00
// Implements ERC20
string public symbol;
2021-05-02 16:33:00 +02:00
// Implements ERC20
uint8 public decimals;
2021-05-02 16:33:00 +02:00
// Implements ERC20
mapping (address => uint256) public balanceOf;
2021-05-02 16:33:00 +02:00
// Implements ERC20
2020-12-11 16:42:47 +01:00
mapping (address => mapping (address => uint256)) public allowance;
2023-02-22 11:48:32 +01:00
// Implements Burner
uint256 public totalMinted;
// Implements Burner
2023-03-21 21:28:39 +01:00
uint256 public totalBurned;
2023-02-22 11:48:32 +01:00
2023-03-26 09:07:41 +02:00
// Implements Expire
2023-02-21 21:28:25 +01:00
uint256 public expires;
bool expired;
2023-02-22 11:48:32 +01:00
// Implements ERC20
event Transfer(address indexed _from, address indexed _to, uint256 _value);
2023-02-22 11:48:32 +01:00
// Implements ERC20
event TransferFrom(address indexed _from, address indexed _to, address indexed _spender, uint256 _value);
2023-02-22 11:48:32 +01:00
// Implements ERC20
event Approval(address indexed _owner, address indexed _spender, uint256 _value);
2023-02-22 11:48:32 +01:00
// Implements Minter
2021-05-02 16:33:00 +02:00
event Mint(address indexed _minter, address indexed _beneficiary, uint256 _value);
2023-02-22 11:48:32 +01:00
// Implement Expire
2023-02-21 21:28:25 +01:00
event Expired(uint256 _timestamp);
2023-02-22 11:48:32 +01:00
// Implements Writer
event WriterAdded(address _writer);
// Implements Writer
event WriterRemoved(address _writer);
// Implements Burner
event Burn(uint256 _value);
2023-03-21 21:08:17 +01:00
constructor(string memory _name, string memory _symbol, uint8 _decimals, uint256 _expireTimestamp) {
owner = msg.sender;
name = _name;
symbol = _symbol;
decimals = _decimals;
2023-02-21 21:28:25 +01:00
expires = _expireTimestamp;
}
2023-02-22 11:48:32 +01:00
// Implements ERC20
2023-03-21 21:08:17 +01:00
function totalSupply() public view returns (uint256) {
2023-03-21 21:28:39 +01:00
return totalMinted - totalBurned;
2023-02-22 11:48:32 +01:00
}
// Implements Minter
mapping(address => bool) writers;
2021-04-04 14:47:32 +02:00
function mintTo(address _to, uint256 _value) public returns (bool) {
2023-02-22 11:48:32 +01:00
require(writers[msg.sender] || msg.sender == owner);
2021-04-04 14:47:32 +02:00
balanceOf[_to] += _value;
2023-02-22 11:48:32 +01:00
totalMinted += _value;
2021-05-02 16:33:00 +02:00
emit Mint(msg.sender, _to, _value);
return true;
}
2023-03-26 09:07:41 +02:00
// Implements Minter
// Implements ERC5679Ext20
function mint(address _to, uint256 _value, bytes calldata _data) public {
_data;
mintTo(_to, _value);
}
2023-02-22 11:48:32 +01:00
// Implements Writer
2023-02-21 21:28:25 +01:00
function addWriter(address _minter) public returns (bool) {
require(msg.sender == owner);
2023-02-22 11:48:32 +01:00
writers[_minter] = true;
return true;
}
2023-02-22 11:48:32 +01:00
// Implements Writer
2023-03-26 09:07:41 +02:00
function deleteWriter(address _minter) public returns (bool) {
require(msg.sender == owner || msg.sender == _minter);
2023-02-22 11:48:32 +01:00
writers[_minter] = false;
return true;
}
2023-02-22 11:48:32 +01:00
// Implements Writer
2023-02-21 21:28:25 +01:00
function isWriter(address _minter) public view returns(bool) {
2023-02-22 11:48:32 +01:00
return writers[_minter] || _minter == owner;
2023-02-21 21:28:25 +01:00
}
2023-02-22 11:48:32 +01:00
// Implements Expire
2023-02-21 21:28:25 +01:00
function applyExpiry() public returns(uint8) {
if (expires == 0) {
return 0;
}
if (expired) {
return 1;
}
if (block.timestamp >= expires) {
expired = true;
emit Expired(block.timestamp);
return 2;
}
return 0;
}
2021-05-02 16:33:00 +02:00
// Implements ERC20
function transfer(address _to, uint256 _value) public returns (bool) {
2023-02-21 21:28:25 +01:00
require(applyExpiry() == 0);
2020-12-06 17:37:50 +01:00
require(balanceOf[msg.sender] >= _value);
balanceOf[msg.sender] -= _value;
balanceOf[_to] += _value;
emit Transfer(msg.sender, _to, _value);
return true;
}
2023-02-22 11:48:32 +01:00
// Implements Burner
function burn(uint256 _value) public returns (bool) {
require(msg.sender == owner, 'ERR_ACCESS');
require(balanceOf[msg.sender] >= _value, 'ERR_FUNDS');
balanceOf[msg.sender] -= _value;
2023-03-21 21:28:39 +01:00
totalBurned += _value;
2023-02-22 11:48:32 +01:00
emit Burn(_value);
2023-03-21 21:08:17 +01:00
return true;
2023-02-22 11:48:32 +01:00
}
2023-03-26 09:07:41 +02:00
// Implements Burner
function burn() public returns(bool) {
return burn(balanceOf[msg.sender]);
}
// Implements Burner
// Implements ERC5679Ext20
function burn(address _from, uint256 _value, bytes calldata _data) public {
require(msg.sender == _from, 'ERR_NOT_SELF');
_data;
burn(_value);
}
2021-05-02 16:33:00 +02:00
// Implements ERC20
function transferFrom(address _from, address _to, uint256 _value) public returns (bool) {
2023-02-21 21:28:25 +01:00
require(applyExpiry() == 0);
2020-12-11 16:42:47 +01:00
require(allowance[_from][msg.sender] >= _value);
2020-12-06 17:37:50 +01:00
require(balanceOf[_from] >= _value);
2020-12-11 16:42:47 +01:00
allowance[_from][msg.sender] = allowance[_from][msg.sender] - _value;
balanceOf[_from] -= _value;
balanceOf[_to] += _value;
emit TransferFrom(_from, _to, msg.sender, _value);
return true;
}
2021-05-02 16:33:00 +02:00
// Implements ERC20
function approve(address _spender, uint256 _value) public returns (bool) {
2023-02-21 21:28:25 +01:00
require(applyExpiry() == 0);
2021-06-26 10:30:17 +02:00
if (_value > 0) {
require(allowance[msg.sender][_spender] == 0);
}
allowance[msg.sender][_spender] = _value;
emit Approval(msg.sender, _spender, _value);
return true;
}
2021-05-02 16:33:00 +02:00
2021-12-09 06:23:21 +01:00
// Implements EIP173
function transferOwnership(address _newOwner) public returns (bool) {
2022-03-11 06:55:16 +01:00
require(msg.sender == owner);
2021-12-09 06:23:21 +01:00
owner = _newOwner;
2023-03-21 21:08:17 +01:00
return true;
2021-12-09 06:23:21 +01:00
}
2021-05-02 16:33:00 +02:00
// Implements EIP165
2023-03-21 21:08:17 +01:00
function supportsInterface(bytes4 _sum) public pure returns (bool) {
2023-03-21 21:28:39 +01:00
if (_sum == 0xb61bc941) { // ERC20
2021-05-02 16:33:00 +02:00
return true;
}
if (_sum == 0x449a52f8) { // Minter
return true;
}
if (_sum == 0x01ffc9a7) { // EIP165
return true;
}
2021-12-09 06:23:21 +01:00
if (_sum == 0x9493f8b2) { // EIP173
return true;
}
2023-02-22 11:48:32 +01:00
if (_sum == 0xabe1f1f5) { // Writer
return true;
}
2023-03-21 21:28:39 +01:00
if (_sum == 0xb1110c1b) { // Burner
2023-02-22 11:48:32 +01:00
return true;
}
2023-03-26 09:07:41 +02:00
if (_sum == 0x841a0e94) { // Expire
return true;
}
2021-05-02 16:33:00 +02:00
return false;
}
}