Update interfaces, add ERC5679 aliases

This commit is contained in:
lash 2023-03-26 07:26:02 +01:00
parent badfa4838a
commit d4906529a3
Signed by: lash
GPG Key ID: 21D2E7BB88C2A746
5 changed files with 89 additions and 37 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,6 +1,6 @@
[metadata] [metadata]
name = erc20-demurrage-token name = erc20-demurrage-token
version = 0.5.0 version = 0.5.1
description = ERC20 token with redistributed continual demurrage description = ERC20 token with redistributed continual demurrage
author = Louis Holbrook author = Louis Holbrook
author_email = dev@holbrook.no author_email = dev@holbrook.no

View File

@ -1,9 +1,9 @@
pragma solidity >= 0.8.0; pragma solidity >= 0.8.0;
import "aux/ABDKMath64x64.sol"; import "aux/ABDKMath64x64.sol";
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: AGPL-3.0-or-later
contract DemurrageTokenSingleNocap { contract DemurrageTokenSingleNocap {
struct redistributionItem { struct redistributionItem {
@ -11,7 +11,7 @@ contract DemurrageTokenSingleNocap {
uint72 value; uint72 value;
uint64 demurrage; uint64 demurrage;
} }
redistributionItem[] public redistributions; // uint51(unused) | uint64(demurrageModifier) | uint36(participants) | uint72(value) | uint32(period) redistributionItem[] public redistributions;
// Account balances // Account balances
mapping (address => uint256) account; mapping (address => uint256) account;
@ -23,7 +23,7 @@ contract DemurrageTokenSingleNocap {
// Cached demurrage timestamp; the timestamp for which demurrageAmount was last calculated // Cached demurrage timestamp; the timestamp for which demurrageAmount was last calculated
uint256 public demurrageTimestamp; uint256 public demurrageTimestamp;
// Implements EIP172 // Implements EIP173
address public owner; address public owner;
address newOwner; address newOwner;
@ -37,8 +37,6 @@ contract DemurrageTokenSingleNocap {
// Implements ERC20 // Implements ERC20
uint256 public immutable decimals; uint256 public immutable decimals;
// Implements ERC20
//uint256 public totalSupply;
uint256 supply; uint256 supply;
// Last executed period // Last executed period
@ -48,7 +46,7 @@ contract DemurrageTokenSingleNocap {
uint256 public totalSink; uint256 public totalSink;
// Value of burnt tokens (burnt tokens do not decay) // Value of burnt tokens (burnt tokens do not decay)
uint256 public burned; uint256 burned;
// 128 bit resolution of the demurrage divisor // 128 bit resolution of the demurrage divisor
// (this constant x 1000000 is contained within 128 bits) // (this constant x 1000000 is contained within 128 bits)
@ -93,7 +91,7 @@ contract DemurrageTokenSingleNocap {
// Implements ERC20 // Implements ERC20
event Approval(address indexed _owner, address indexed _spender, uint256 _value); event Approval(address indexed _owner, address indexed _spender, uint256 _value);
// New tokens minted // Implements Minter
event Mint(address indexed _minter, address indexed _beneficiary, uint256 _value); event Mint(address indexed _minter, address indexed _beneficiary, uint256 _value);
// New demurrage cache milestone calculated // New demurrage cache milestone calculated
@ -109,23 +107,27 @@ contract DemurrageTokenSingleNocap {
//event Debug(bytes32 _foo); //event Debug(bytes32 _foo);
event Debug(int128 indexed _foo, uint256 indexed _bar); event Debug(int128 indexed _foo, uint256 indexed _bar);
// Emitted when tokens are burned // Implements Burn
event Burn(address indexed _burner, uint256 _value); event Burn(address indexed _burner, uint256 _value);
// EIP173 // EIP173
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); // EIP173 event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); // EIP173
// Implements Expire
event Expired(uint256 _timestamp); event Expired(uint256 _timestamp);
event Cap(uint256 indexed _oldCap, uint256 _newCap); event Cap(uint256 indexed _oldCap, uint256 _newCap);
// Implements Sealer // Implements Seal
uint256 public sealState; uint256 public sealState;
uint8 constant WRITER_STATE = 1; uint8 constant WRITER_STATE = 1;
uint8 constant SINK_STATE = 2; uint8 constant SINK_STATE = 2;
uint8 constant EXPIRY_STATE = 4; uint8 constant EXPIRY_STATE = 4;
uint8 constant CAP_STATE = 8; uint8 constant CAP_STATE = 8;
// Implements Seal
uint256 constant public maxSealState = 15; uint256 constant public maxSealState = 15;
// Implements Seal
event SealStateChange(bool indexed _final, uint256 _sealState); event SealStateChange(bool indexed _final, uint256 _sealState);
@ -157,7 +159,6 @@ contract DemurrageTokenSingleNocap {
sinkAddress = _defaultSinkAddress; sinkAddress = _defaultSinkAddress;
} }
// Implements Sealer
function seal(uint256 _state) public returns(uint256) { function seal(uint256 _state) public returns(uint256) {
require(_state < 16, 'ERR_INVALID_STATE'); require(_state < 16, 'ERR_INVALID_STATE');
require(_state & sealState == 0, 'ERR_ALREADY_LOCKED'); require(_state & sealState == 0, 'ERR_ALREADY_LOCKED');
@ -166,7 +167,6 @@ contract DemurrageTokenSingleNocap {
return uint256(sealState); return uint256(sealState);
} }
// Implements Sealer
function isSealed(uint256 _state) public view returns(bool) { function isSealed(uint256 _state) public view returns(bool) {
require(_state < maxSealState); require(_state < maxSealState);
if (_state == 0) { if (_state == 0) {
@ -175,6 +175,9 @@ contract DemurrageTokenSingleNocap {
return _state & sealState == _state; return _state & sealState == _state;
} }
// Set when token expires.
// Value is set it terms of redistribution periods.
// Cannot be set to a time in the past.
function setExpirePeriod(uint256 _expirePeriod) public { function setExpirePeriod(uint256 _expirePeriod) public {
uint256 r; uint256 r;
@ -185,7 +188,9 @@ contract DemurrageTokenSingleNocap {
require(r > expires); require(r > expires);
expires = r; expires = r;
} }
// Change max token supply.
// Can only increase supply cap, not decrease.
function setMaxSupply(uint256 _cap) public { function setMaxSupply(uint256 _cap) public {
require(!isSealed(CAP_STATE)); require(!isSealed(CAP_STATE));
require(msg.sender == owner); require(msg.sender == owner);
@ -222,6 +227,7 @@ contract DemurrageTokenSingleNocap {
} }
// Given address will be allowed to call the mintTo() function // Given address will be allowed to call the mintTo() function
// Implements Writer
function addWriter(address _minter) public returns (bool) { function addWriter(address _minter) public returns (bool) {
require(!isSealed(WRITER_STATE)); require(!isSealed(WRITER_STATE));
require(msg.sender == owner); require(msg.sender == owner);
@ -230,6 +236,7 @@ contract DemurrageTokenSingleNocap {
} }
// Given address will no longer be allowed to call the mintTo() function // Given address will no longer be allowed to call the mintTo() function
// Implements Writer
function deleteWriter(address _minter) public returns (bool) { function deleteWriter(address _minter) public returns (bool) {
require(!isSealed(WRITER_STATE)); require(!isSealed(WRITER_STATE));
require(msg.sender == owner || _minter == msg.sender); require(msg.sender == owner || _minter == msg.sender);
@ -237,6 +244,11 @@ contract DemurrageTokenSingleNocap {
return true; return true;
} }
// Implements Writer
function isWriter(address _minter) public view returns(bool) {
return minter[_minter];
}
/// Implements ERC20 /// Implements ERC20
function balanceOf(address _account) public view returns (uint256) { function balanceOf(address _account) public view returns (uint256) {
int128 baseBalance; int128 baseBalance;
@ -301,7 +313,8 @@ contract DemurrageTokenSingleNocap {
// Creates new tokens out of thin air, and allocates them to the given address // Creates new tokens out of thin air, and allocates them to the given address
// Triggers tax // Triggers tax
function mintTo(address _beneficiary, uint256 _amount) external returns (bool) { // Implements Minter
function mintTo(address _beneficiary, uint256 _amount) public returns (bool) {
uint256 baseAmount; uint256 baseAmount;
require(applyExpiry() == 0); require(applyExpiry() == 0);
@ -320,6 +333,18 @@ contract DemurrageTokenSingleNocap {
return true; return true;
} }
// Implements Minter
function mint(address _beneficiary, uint256 _amount, bytes calldata _data) public {
_data;
mintTo(_beneficiary, _amount);
}
// Implements Minter
function safeMint(address _beneficiary, uint256 _amount, bytes calldata _data) public {
_data;
mintTo(_beneficiary, _amount);
}
// Deserializes the redistribution word // Deserializes the redistribution word
function toRedistribution(uint256 _participants, int128 _demurrageModifier, uint256 _value, uint256 _period) public pure returns(redistributionItem memory) { function toRedistribution(uint256 _participants, int128 _demurrageModifier, uint256 _value, uint256 _period) public pure returns(redistributionItem memory) {
redistributionItem memory redistribution; redistributionItem memory redistribution;
@ -508,6 +533,7 @@ contract DemurrageTokenSingleNocap {
return (block.timestamp - _target) / 60; return (block.timestamp - _target) / 60;
} }
// Equality check for empty redistribution data
function isEmptyRedistribution(redistributionItem memory _redistribution) public pure returns(bool) { function isEmptyRedistribution(redistributionItem memory _redistribution) public pure returns(bool) {
if (_redistribution.period > 0) { if (_redistribution.period > 0) {
return false; return false;
@ -545,7 +571,8 @@ contract DemurrageTokenSingleNocap {
return ABDKMath64x64.toUInt(r); return ABDKMath64x64.toUInt(r);
} }
// Implements ERC20, triggers tax and/or redistribution // Triggers tax and/or redistribution
// Implements ERC20
function approve(address _spender, uint256 _value) public returns (bool) { function approve(address _spender, uint256 _value) public returns (bool) {
uint256 baseValue; uint256 baseValue;
uint8 ex; uint8 ex;
@ -595,7 +622,8 @@ contract DemurrageTokenSingleNocap {
return true; return true;
} }
// Implements ERC20, triggers tax and/or redistribution // Triggers tax and/or redistribution
// Implements ERC20
function transfer(address _to, uint256 _value) public returns (bool) { function transfer(address _to, uint256 _value) public returns (bool) {
uint256 baseValue; uint256 baseValue;
bool result; bool result;
@ -615,7 +643,8 @@ contract DemurrageTokenSingleNocap {
return result; return result;
} }
// Implements ERC20, triggers tax and/or redistribution // Triggers tax and/or redistribution
// Implements ERC20
function transferFrom(address _from, address _to, uint256 _value) public returns (bool) { function transferFrom(address _from, address _to, uint256 _value) public returns (bool) {
uint256 baseValue; uint256 baseValue;
bool result; bool result;
@ -649,26 +678,20 @@ contract DemurrageTokenSingleNocap {
// Implements EIP173 // Implements EIP173
function transferOwnership(address _newOwner) public returns (bool) { function transferOwnership(address _newOwner) public returns (bool) {
require(msg.sender == owner);
newOwner = _newOwner;
return true;
}
// Implements OwnedAccepter
function acceptOwnership() public returns (bool) {
address oldOwner; address oldOwner;
require(msg.sender == newOwner); require(msg.sender == owner);
oldOwner = owner; oldOwner = owner;
owner = newOwner; owner = _newOwner;
newOwner = address(0);
emit OwnershipTransferred(oldOwner, owner); emit OwnershipTransferred(oldOwner, owner);
return true; return true;
} }
// Explicitly and irretrievably burn tokens // Explicitly and irretrievably burn tokens
// Only token minters can burn tokens // Only token minters can burn tokens
function burn(uint256 _value) public returns (bool) { // Implements Burner
function burn(uint256 _value) public returns(bool) {
require(applyExpiry() == 0); require(applyExpiry() == 0);
require(minter[msg.sender] || msg.sender == owner, 'ERR_ACCESS'); require(minter[msg.sender] || msg.sender == owner, 'ERR_ACCESS');
require(_value <= account[msg.sender]); require(_value <= account[msg.sender]);
@ -681,17 +704,31 @@ contract DemurrageTokenSingleNocap {
return true; return true;
} }
// Implements Burner
function burn(address _from, uint256 _value, bytes calldata _data) public {
require(_from == msg.sender, 'ERR_ONLY_SELF_BURN');
_data;
burn(_value);
}
// Implements Burner
function burn() public returns(bool) {
return burn(account[msg.sender]);
}
// Implements ERC20 // Implements ERC20
function totalSupply() public view returns (uint256) { function totalSupply() public view returns (uint256) {
return supply - burned; return supply - burned;
} }
// Return total number of burned tokens // Return total number of burned tokens
// Implements Burner
function totalBurned() public view returns (uint256) { function totalBurned() public view returns (uint256) {
return burned; return burned;
} }
// Return total number of tokens ever minted // Return total number of tokens ever minted
// Implements Burner
function totalMinted() public view returns (uint256) { function totalMinted() public view returns (uint256) {
return supply; return supply;
} }
@ -699,16 +736,31 @@ contract DemurrageTokenSingleNocap {
// Implements EIP165 // Implements EIP165
function supportsInterface(bytes4 _sum) public pure returns (bool) { function supportsInterface(bytes4 _sum) public pure returns (bool) {
if (_sum == 0xc6bb4b70) { // ERC20 if (_sum == 0xb61bc941) { // ERC20
return true; return true;
} }
if (_sum == 0x449a52f8) { // Minter if (_sum == 0x5878bcf4) { // Minter
return true; return true;
} }
if (_sum == 0x01ffc9a7) { // EIP165 if (_sum == 0xbc4babdd) { // Burner
return true; return true;
} }
if (_sum == 0x9493f8b2) { // EIP173 if (_sum == 0x0d7491f8) { // Seal
return true;
}
if (_sum == 0xabe1f1f5) { // Writer
return true;
}
if (_sum == 0xcb52c823) { // Expire
return true;
}
if (_sum == 0x01ffc9a7) { // ERC165
return true;
}
if (_sum == 0x9493f8b2) { // ERC173
return true;
}
if (_sum == 0xd0017968) { // ERC5678Ext20
return true; return true;
} }
return false; return false;