WIP rehabilitating test basic

This commit is contained in:
lash 2023-02-09 11:44:20 +00:00
parent ae2c1b4124
commit f785925eb5
Signed by: lash
GPG Key ID: 21D2E7BB88C2A746
6 changed files with 81 additions and 77 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -24,6 +24,7 @@ from hexathon import (
# local imports
from erc20_demurrage_token.data import data_dir
from erc20_demurrage_token.fixed import from_fixed
logg = logging.getLogger(__name__)
@ -100,7 +101,8 @@ class DemurrageToken(ERC20):
@staticmethod
def abi(multi=True, cap=False):
name = DemurrageToken.__to_contract_name(multi, cap)
#name = DemurrageToken.__to_contract_name(multi, cap)
name = 'DemurrageTokenSingleNocap'
if DemurrageToken.__abi.get(name) == None:
f = open(os.path.join(data_dir, name + '.json'), 'r')
DemurrageToken.__abi[name] = json.load(f)
@ -110,7 +112,8 @@ class DemurrageToken(ERC20):
@staticmethod
def bytecode(multi=True, cap=False):
name = DemurrageToken.__to_contract_name(multi, cap)
#name = DemurrageToken.__to_contract_name(multi, cap)
name = 'DemurrageTokenSingleNocap'
if DemurrageToken.__bytecode.get(name) == None:
f = open(os.path.join(data_dir, name + '.bin'), 'r')
DemurrageToken.__bytecode[name] = f.read()
@ -561,7 +564,8 @@ class DemurrageToken(ERC20):
@classmethod
def parse_demurrage_amount(self, v):
return abi_decode_single(ABIContractType.UINT256, v)
# return abi_decode_single(ABIContractType.UINT256, v)
return from_fixed(v)
@classmethod

View File

@ -1,6 +1,7 @@
# standard imports
import logging
import os
import math
# external imports
from chainlib.eth.unittest.ethtester import EthTesterCase
@ -19,6 +20,10 @@ from erc20_demurrage_token import (
DemurrageTokenSettings,
DemurrageToken,
)
from erc20_demurrage_token.fixed import (
to_fixed,
from_fixed,
)
logg = logging.getLogger()
@ -26,8 +31,7 @@ logg = logging.getLogger()
TAX_LEVEL = int(10000 * 2) # 2%
# calc "1-(0.98)^(1/518400)" <- 518400 = 30 days of blocks
# 0.00000003897127107225
#PERIOD = int(60/BLOCKTIME) * 60 * 24 * 30 # month
PERIOD = 10
PERIOD = 43200
class TestTokenDeploy:
@ -41,7 +45,8 @@ class TestTokenDeploy:
self.settings.name = token_name
self.settings.symbol = token_symbol
self.settings.decimals = 6
self.settings.demurrage_level = tax_level ** (1 / period)
tax_level_input = to_fixed((1 - (tax_level / 1000000)) ** (1 / period))
self.settings.demurrage_level = tax_level_input
self.settings.period_minutes = period
self.settings.sink_address = sink_address
self.sink_address = self.settings.sink_address
@ -59,11 +64,10 @@ class TestTokenDeploy:
self.start_time = int(r['timestamp'])
self.default_supply = supply
#self.default_supply_cap = int(self.default_supply * 10)
self.default_supply_cap = 0
def deploy(self, rpc, deployer_address, interface, mode, supply_cap=0):
def deploy(self, rpc, deployer_address, interface, supply_cap=0):
tx_hash = None
o = None
(tx_hash, o) = interface.constructor(deployer_address, self.settings, redistribute=False, cap=0)
@ -100,7 +104,7 @@ class TestDemurrage(EthTesterCase):
def deploy(self, interface):
self.address = self.deployer.deploy(self.rpc, self.accounts[0], interface, mode, supply_cap=self.default_supply_cap)
self.address = self.deployer.deploy(self.rpc, self.accounts[0], interface, supply_cap=self.default_supply_cap)
self.start_block = self.deployer.start_block
self.start_time = self.deployer.start_time
self.tax_level = self.deployer.tax_level
@ -117,6 +121,12 @@ class TestDemurrage(EthTesterCase):
logg.debug('asserted within lower {} <= {} <= {}'.format(lower_target, v, target))
def assert_equal_decimals(self, v, target, precision):
target = int(target * (10 ** precision))
target = target / (10 ** precision)
self.assertEqual(v, target)
def tearDown(self):
pass
@ -130,5 +140,3 @@ class TestDemurrageDefault(TestDemurrage):
c = DemurrageToken(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle)
self.deploy(c)
logg.info('deployed with mode {}'.format(self.mode))

View File

@ -18,7 +18,7 @@ from chainlib.eth.block import (
from erc20_demurrage_token import DemurrageToken
# test imports
from erc20_demurrage_token.unittest.base import TestDemurrageDefault
from erc20_demurrage_token.unittest import TestDemurrageDefault
logging.basicConfig(level=logging.DEBUG)
logg = logging.getLogger()
@ -55,7 +55,8 @@ class TestBasic(TestDemurrageDefault):
def test_apply_demurrage_limited(self):
modifier = (10 ** 28)
#modifier = (10 ** 28)
modifier = 1
nonce_oracle = RPCNonceOracle(self.accounts[0], self.rpc)
c = DemurrageToken(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle)
@ -65,8 +66,8 @@ class TestBasic(TestDemurrageDefault):
demurrage_amount = c.parse_demurrage_amount(r)
self.assertEqual(modifier, demurrage_amount)
self.backend.time_travel(self.start_time + 120)
(tx_hash, o) = c.apply_demurrage(self.address, sender_address=self.accounts[0], limit=1)
self.backend.time_travel(self.start_time + (60 * 43200))
(tx_hash, o) = c.apply_demurrage(self.address, sender_address=self.accounts[0], limit=20000)
r = self.rpc.do(o)
o = receipt(tx_hash)
r = self.rpc.do(o)
@ -75,13 +76,12 @@ class TestBasic(TestDemurrageDefault):
o = c.demurrage_amount(self.address, sender_address=self.accounts[0])
r = self.rpc.do(o)
demurrage_amount = c.parse_demurrage_amount(r)
modifier_base = 1000000 - self.tax_level
modifier = int(modifier_base * (10 ** 22)) # 38 decimal places minus 6 (1000000)
self.assertEqual(modifier, demurrage_amount)
self.assert_equal_decimals(0.9906, demurrage_amount, 4)
def test_apply_demurrage(self):
modifier = (10 ** 28)
#modifier = (10 ** 28)
modifier = 1
nonce_oracle = RPCNonceOracle(self.accounts[0], self.rpc)
c = DemurrageToken(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle)
@ -97,7 +97,7 @@ class TestBasic(TestDemurrageDefault):
b = self.rpc.do(o)
logg.debug('block {} start {}'.format(b['timestamp'], self.start_time))
self.backend.time_travel(self.start_time + 2)
self.backend.time_travel(self.start_time + (60 * 43200))
(tx_hash, o) = c.apply_demurrage(self.address, sender_address=self.accounts[0])
r = self.rpc.do(o)
o = receipt(tx_hash)
@ -107,9 +107,9 @@ class TestBasic(TestDemurrageDefault):
o = c.demurrage_amount(self.address, sender_address=self.accounts[0])
r = self.rpc.do(o)
demurrage_amount = c.parse_demurrage_amount(r)
self.assertEqual(modifier, demurrage_amount)
self.assert_equal_decimals(0.98, demurrage_amount, 2)
self.backend.time_travel(self.start_time + 61)
self.backend.time_travel(self.start_time + (60 * 43200 * 2))
(tx_hash, o) = c.apply_demurrage(self.address, sender_address=self.accounts[0])
r = self.rpc.do(o)
o = receipt(tx_hash)
@ -120,28 +120,10 @@ class TestBasic(TestDemurrageDefault):
demurrage_amount = c.parse_demurrage_amount(r)
modifier_base = 1000000 - self.tax_level
modifier = int(modifier_base * (10 ** 22)) # 38 decimal places minus 6 (1000000)
self.assertEqual(modifier, demurrage_amount)
self.backend.time_travel(self.start_time + 601)
(tx_hash, o) = c.apply_demurrage(self.address, sender_address=self.accounts[0])
r = self.rpc.do(o)
o = receipt(tx_hash)
r = self.rpc.do(o)
self.assertEqual(r['status'], 1)
o = c.demurrage_amount(self.address, sender_address=self.accounts[0])
r = self.rpc.do(o)
demurrage_amount = c.parse_demurrage_amount(r)
modifier_base = ((1000000 - self.tax_level) / 1000000) ** 10
logg.warning('mod base {}'.format(modifier_base))
modifier = int(modifier_base * (10 ** 12))
rounding_tolerance_nano = 4000000 # 0.000004% precision
demurrage_amount_truncate = int(demurrage_amount / (10 ** 16)) # equals 38 decimal places - 14 for the modifier magniture - 2 for percent int calc + 6 for token decimals <- TODO verify this calc
self.assertGreaterEqual(modifier, demurrage_amount_truncate - rounding_tolerance_nano)
self.assertLessEqual(modifier, demurrage_amount_truncate)
self.assert_equal_decimals(0.9604, demurrage_amount, 4)
def test_mint(self):
def test_mint_balance(self):
nonce_oracle = RPCNonceOracle(self.accounts[0], self.rpc)
c = DemurrageToken(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle)
(tx_hash, o) = c.mint_to(self.address, self.accounts[0], self.accounts[1], 1024)
@ -160,16 +142,19 @@ class TestBasic(TestDemurrageDefault):
o = receipt(tx_hash)
r = self.rpc.do(o)
self.assertEqual(r['status'], 1)
o = c.balance_of(self.address, self.accounts[1], sender_address=self.accounts[0])
r = self.rpc.do(o)
balance = c.parse_balance_of(r)
self.assertEqual(balance, 2000)
self.backend.time_travel(self.start_time + 61)
self.backend.time_travel(self.start_time + (60 * 43200))
(tx_hash, o) = c.apply_demurrage(self.address, sender_address=self.accounts[0])
r = self.rpc.do(o)
o = receipt(tx_hash)
r = self.rpc.do(o)
self.assertEqual(r['status'], 1)
o = c.balance_of(self.address, self.accounts[1], sender_address=self.accounts[0])
r = self.rpc.do(o)
balance = c.parse_balance_of(r)

View File

@ -90,7 +90,7 @@ contract DemurrageTokenSingleCap {
event Mint(address indexed _minter, address indexed _beneficiary, uint256 _value);
// New demurrage cache milestone calculated
event Decayed(uint256 indexed _period, uint256 indexed _periodCount, uint256 indexed _oldAmount, uint256 _newAmount);
event Decayed(uint256 indexed _period, uint256 indexed _periodCount, int128 indexed _oldAmount, int128 _newAmount);
// When a new period threshold has been crossed
event Period(uint256 _period);
@ -214,6 +214,10 @@ contract DemurrageTokenSingleCap {
return true;
}
function changePeriod() public {
applyDemurrage();
}
// Creates new tokens out of thin air, and allocates them to the given address
// Triggers tax
function mintTo(address _beneficiary, uint256 _amount) external returns (bool) {
@ -221,7 +225,7 @@ contract DemurrageTokenSingleCap {
require(minter[msg.sender], 'ERR_ACCESS');
//changePeriod();
changePeriod();
baseAmount = toBaseAmount(_amount);
supply += _amount;
increaseBaseBalance(_beneficiary, baseAmount);
@ -328,33 +332,38 @@ contract DemurrageTokenSingleCap {
return (block.timestamp - _lastTimestamp) / 60;
}
// // Calculate and cache the demurrage value corresponding to the (period of the) time of the method call
// function applyDemurrage() public returns (bool) {
// return applyDemurrageLimited(0);
// }
//
// function applyDemurrageLimited(uint256 _rounds) public returns (bool) {
// uint256 periodCount;
// uint256 lastDemurrageAmount;
//
// periodCount = getMinutesDelta(demurrageTimestamp);
// if (periodCount == 0) {
// return false;
// }
// lastDemurrageAmount = demurrageAmount;
//
// // safety limit for exponential calculation to ensure that we can always
// // execute this code no matter how much time passes.
// if (_rounds > 0 && _rounds < periodCount) {
// periodCount = _rounds;
// }
//
// demurrageAmount = uint128(decayBy(lastDemurrageAmount, periodCount));
// //demurragePeriod = epochPeriodCount;
// demurrageTimestamp = demurrageTimestamp + (periodCount * 60);
// emit Decayed(demurrageTimestamp, periodCount, lastDemurrageAmount, demurrageAmount);
// return true;
// }
// Calculate and cache the demurrage value corresponding to the (period of the) time of the method call
function applyDemurrage() public returns (uint256) {
return applyDemurrageLimited(0);
}
function applyDemurrageLimited(uint256 _rounds) public returns (uint256) {
int128 v;
uint256 periodCount;
int128 periodPoint;
int128 lastDemurrageAmount;
periodCount = getMinutesDelta(demurrageTimestamp);
if (periodCount == 0) {
return 0;
}
lastDemurrageAmount = demurrageAmount;
// safety limit for exponential calculation to ensure that we can always
// execute this code no matter how much time passes.
if (_rounds > 0 && _rounds < periodCount) {
periodCount = _rounds;
}
periodPoint = ABDKMath64x64.fromUInt(periodCount);
v = ABDKMath64x64.mul(taxLevel, periodPoint);
v = ABDKMath64x64.exp(v);
demurrageAmount = ABDKMath64x64.mul(demurrageAmount, v);
demurrageTimestamp = demurrageTimestamp + (periodCount * 60);
emit Decayed(demurrageTimestamp, periodCount, lastDemurrageAmount, demurrageAmount);
return periodCount;
}
// Return timestamp of start of period threshold
function getPeriodTimeDelta(uint256 _periodCount) public view returns (uint256) {
@ -436,8 +445,6 @@ contract DemurrageTokenSingleCap {
valuePoint = ABDKMath64x64.fromUInt(_value);
periodPoint = ABDKMath64x64.fromUInt(_period);
//valuePoint -= ABDKMath64x64.mul(ABDKMath64x64.exp(ABDKMath64x64.mul(taxLevel, periodPoint)), valuePoint);
//valuePoint -= ABDKMath64x64.exp(ABDKMath64x64.mul(taxLevel, periodPoint));
v = ABDKMath64x64.mul(taxLevel, periodPoint);
v = ABDKMath64x64.exp(v);
v = ABDKMath64x64.mul(valuePoint, v);