Add redistribution single minute demurrage test
This commit is contained in:
parent
399e24764a
commit
e47720fa04
@ -148,10 +148,10 @@ class DemurrageTokenSimulation:
|
||||
def get_period(self):
|
||||
return self.period
|
||||
|
||||
def get_demurrage_modifier(self):
|
||||
def get_demurrage(self):
|
||||
o = self.caller_contract.demurrage_amount(self.address, sender_address=self.caller_address)
|
||||
r = self.rpc.do(o)
|
||||
return float(self.caller_contract.parse_demurrage_amount(r) / (10 ** 38))
|
||||
return float(self.caller_contract.parse_demurrage_amount(r) / (10 ** 40))
|
||||
|
||||
|
||||
def from_units(self, v):
|
||||
|
@ -16,7 +16,7 @@ settings.name = 'Simulated Demurrage Token'
|
||||
settings.symbol = 'SIM'
|
||||
settings.decimals = 6
|
||||
settings.demurrage_level = int(decay_per_minute*(10**40))
|
||||
settings.period_minutes = 10800 # 1 week in minutes
|
||||
settings.period_minutes = 1 # 1 week in minutes
|
||||
chain = 'evm:foochain:42'
|
||||
cap = (10 ** 6) * (10 ** 12)
|
||||
|
||||
@ -55,15 +55,15 @@ period = sim.get_period()
|
||||
print('start {} now {} period {} minutes passed {}'.format(start, timestamp, period, minutes))
|
||||
|
||||
|
||||
contract_demurrage = 1 - sim.get_demurrage_modifier() # demurrage in percent (float)
|
||||
frontend_demurrage = ((1 - decay_per_minute) ** minutes / 100) # corresponding demurrage modifier (float)
|
||||
contract_demurrage = 1 - sim.get_demurrage() # demurrage in percent (float)
|
||||
frontend_demurrage = 1.0 - ((1 - decay_per_minute) ** minutes) # corresponding demurrage modifier (float)
|
||||
demurrage_delta = contract_demurrage - frontend_demurrage # difference between demurrage in contract and demurrage calculated in frontend
|
||||
|
||||
alice_checksum = 50000000 - (50000000 * frontend_demurrage) + (200000000 * frontend_demurrage) # alice's balance calculated with frontend demurrage
|
||||
print("""alice frontend balance {}
|
||||
alice contract balance {}
|
||||
frontend demurrage {}
|
||||
contract demurrage {}
|
||||
frontend demurrage {:f}
|
||||
contract demurrage {:f}
|
||||
demurrage delta {}""".format(
|
||||
alice_checksum,
|
||||
sim.balance(alice),
|
||||
|
@ -163,3 +163,56 @@ class TestDemurrageCap(TestDemurrage):
|
||||
self.deploy(c, self.mode)
|
||||
|
||||
logg.info('deployed with mode {}'.format(self.mode))
|
||||
|
||||
|
||||
|
||||
class TestDemurrageUnit(TestDemurrage):
|
||||
|
||||
def setUp(self):
|
||||
super(TestDemurrage, self).setUp()
|
||||
|
||||
self.tax_level = 50
|
||||
self.period_seconds = 60
|
||||
|
||||
nonce_oracle = RPCNonceOracle(self.accounts[0], self.rpc)
|
||||
self.settings = DemurrageTokenSettings()
|
||||
self.settings.name = 'Foo Token'
|
||||
self.settings.symbol = 'FOO'
|
||||
self.settings.decimals = 6
|
||||
self.settings.demurrage_level = self.tax_level * (10 ** 32)
|
||||
self.settings.period_minutes = int(self.period_seconds/60)
|
||||
self.settings.sink_address = self.accounts[9]
|
||||
self.sink_address = self.settings.sink_address
|
||||
|
||||
o = block_latest()
|
||||
self.start_block = self.rpc.do(o)
|
||||
|
||||
o = block_by_number(self.start_block, include_tx=False)
|
||||
r = self.rpc.do(o)
|
||||
|
||||
try:
|
||||
self.start_time = int(r['timestamp'], 16)
|
||||
except TypeError:
|
||||
self.start_time = int(r['timestamp'])
|
||||
|
||||
self.default_supply = 1000000000000
|
||||
self.default_supply_cap = int(self.default_supply * 10)
|
||||
|
||||
nonce_oracle = RPCNonceOracle(self.accounts[0], self.rpc)
|
||||
c = DemurrageToken(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle)
|
||||
|
||||
self.mode = os.environ.get('ERC20_DEMURRAGE_TOKEN_TEST_MODE')
|
||||
unit_valid_modes = [
|
||||
'SingleNocap',
|
||||
'SingleCap',
|
||||
]
|
||||
if self.mode != None:
|
||||
if self.mode not in unit_valid_modes:
|
||||
raise ValueError('Invalid mode "{}" for "unit" contract tests, valid are {}'.format(self.mode, unit_valid_modes))
|
||||
else:
|
||||
self.mode = 'SingleNocap'
|
||||
logg.debug('executing test setup unit mode {}'.format(self.mode))
|
||||
|
||||
self.deploy(c, self.mode)
|
||||
|
||||
logg.info('deployed with mode {}'.format(self.mode))
|
||||
|
138
python/tests/test_redistribution_unit.py
Normal file
138
python/tests/test_redistribution_unit.py
Normal file
@ -0,0 +1,138 @@
|
||||
import os
|
||||
import unittest
|
||||
import json
|
||||
import logging
|
||||
|
||||
# external imports
|
||||
from chainlib.eth.constant import ZERO_ADDRESS
|
||||
from chainlib.eth.nonce import RPCNonceOracle
|
||||
from chainlib.eth.tx import receipt
|
||||
from chainlib.eth.block import (
|
||||
block_latest,
|
||||
block_by_number,
|
||||
)
|
||||
from chainlib.eth.address import to_checksum_address
|
||||
from hexathon import (
|
||||
strip_0x,
|
||||
add_0x,
|
||||
)
|
||||
|
||||
# local imports
|
||||
from erc20_demurrage_token import DemurrageToken
|
||||
|
||||
# test imports
|
||||
from tests.base import TestDemurrageUnit
|
||||
|
||||
logging.basicConfig(level=logging.DEBUG)
|
||||
logg = logging.getLogger()
|
||||
|
||||
testdir = os.path.dirname(__file__)
|
||||
|
||||
|
||||
class TestRedistribution(TestDemurrageUnit):
|
||||
|
||||
def test_single_step(self):
|
||||
nonce_oracle = RPCNonceOracle(self.accounts[0], self.rpc)
|
||||
c = DemurrageToken(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle)
|
||||
|
||||
mint_amount = 100000000
|
||||
|
||||
(tx_hash, o) = c.mint_to(self.address, self.accounts[0], self.accounts[1], mint_amount)
|
||||
self.rpc.do(o)
|
||||
|
||||
self.backend.time_travel(self.start_time + self.period_seconds)
|
||||
|
||||
(tx_hash, o) = c.change_period(self.address, self.accounts[0])
|
||||
self.rpc.do(o)
|
||||
|
||||
expected_balance = int(mint_amount - ((self.tax_level / 1000000) * mint_amount))
|
||||
|
||||
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, expected_balance)
|
||||
|
||||
|
||||
def test_single_step_multi(self):
|
||||
nonce_oracle = RPCNonceOracle(self.accounts[0], self.rpc)
|
||||
c = DemurrageToken(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle)
|
||||
|
||||
mint_amount = 100000000
|
||||
|
||||
for i in range(3):
|
||||
(tx_hash, o) = c.mint_to(self.address, self.accounts[0], self.accounts[i+1], mint_amount)
|
||||
self.rpc.do(o)
|
||||
|
||||
self.backend.time_travel(self.start_time + self.period_seconds)
|
||||
|
||||
(tx_hash, o) = c.change_period(self.address, self.accounts[0])
|
||||
self.rpc.do(o)
|
||||
|
||||
expected_balance = int(mint_amount - ((self.tax_level / 1000000) * mint_amount))
|
||||
|
||||
for i in range(3):
|
||||
o = c.balance_of(self.address, self.accounts[i+1], sender_address=self.accounts[0])
|
||||
r = self.rpc.do(o)
|
||||
balance = c.parse_balance_of(r)
|
||||
self.assertEqual(balance, expected_balance)
|
||||
|
||||
|
||||
def test_single_step_transfer(self):
|
||||
nonce_oracle = RPCNonceOracle(self.accounts[0], self.rpc)
|
||||
c = DemurrageToken(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle)
|
||||
|
||||
mint_amount = 100000000
|
||||
half_mint_amount = int(mint_amount / 2)
|
||||
|
||||
(tx_hash, o) = c.mint_to(self.address, self.accounts[0], self.accounts[1], mint_amount)
|
||||
self.rpc.do(o)
|
||||
|
||||
(tx_hash, o) = c.mint_to(self.address, self.accounts[0], self.accounts[2], mint_amount)
|
||||
self.rpc.do(o)
|
||||
|
||||
nonce_oracle = RPCNonceOracle(self.accounts[1], self.rpc)
|
||||
c = DemurrageToken(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle)
|
||||
(tx_hash, o) = c.transfer(self.address, self.accounts[1], self.accounts[3], half_mint_amount)
|
||||
self.rpc.do(o)
|
||||
|
||||
self.backend.time_travel(self.start_time + self.period_seconds)
|
||||
|
||||
(tx_hash, o) = c.change_period(self.address, self.accounts[1])
|
||||
self.rpc.do(o)
|
||||
|
||||
demurrage_amount = int((self.tax_level / 1000000) * mint_amount)
|
||||
|
||||
expected_balance = mint_amount - demurrage_amount
|
||||
o = c.balance_of(self.address, self.accounts[2], sender_address=self.accounts[0])
|
||||
r = self.rpc.do(o)
|
||||
balance = c.parse_balance_of(r)
|
||||
self.assertEqual(balance, expected_balance)
|
||||
|
||||
half_demurrage_amount = int((self.tax_level / 1000000) * half_mint_amount)
|
||||
|
||||
expected_balance = half_mint_amount - half_demurrage_amount
|
||||
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, expected_balance)
|
||||
|
||||
o = c.balance_of(self.address, self.accounts[3], sender_address=self.accounts[0])
|
||||
r = self.rpc.do(o)
|
||||
balance = c.parse_balance_of(r)
|
||||
self.assertEqual(balance, expected_balance)
|
||||
|
||||
o = c.total_supply(self.address, sender_address=self.accounts[0])
|
||||
r = self.rpc.do(o)
|
||||
supply = c.parse_total_supply(r)
|
||||
|
||||
expected_balance = int(supply * (self.tax_level / 1000000))
|
||||
|
||||
o = c.balance_of(self.address, self.sink_address, sender_address=self.accounts[0])
|
||||
r = self.rpc.do(o)
|
||||
balance = c.parse_balance_of(r)
|
||||
self.assertEqual(balance, expected_balance)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
Reference in New Issue
Block a user