erc20-demurrage-token/python/erc20_demurrage_token/unittest/base.py

158 lines
5.1 KiB
Python
Raw Permalink Normal View History

# standard imports
import logging
2021-06-05 08:45:37 +02:00
import os
2023-02-10 11:05:10 +01:00
import math
# external imports
from chainlib.eth.unittest.ethtester import EthTesterCase
from chainlib.eth.tx import (
receipt,
)
from chainlib.eth.block import (
block_latest,
block_by_number,
)
from chainlib.eth.nonce import RPCNonceOracle
from chainlib.eth.constant import ZERO_ADDRESS
# local imports
from erc20_demurrage_token import (
DemurrageTokenSettings,
DemurrageToken,
)
2023-02-10 11:05:10 +01:00
from dexif import *
logg = logging.getLogger()
#BLOCKTIME = 5 # seconds
TAX_LEVEL = int(10000 * 2) # 2%
# calc "1-(0.98)^(1/518400)" <- 518400 = 30 days of blocks
# 0.00000003897127107225
2023-02-10 11:05:10 +01:00
PERIOD = 43200
class TestTokenDeploy:
2023-02-10 11:05:10 +01:00
"""tax level is ppm, 1000000 = 100%"""
2023-02-10 16:58:31 +01:00
def __init__(self, rpc, token_symbol='FOO', token_name='Foo Token', sink_address=ZERO_ADDRESS, tax_level=TAX_LEVEL, period=PERIOD):
2022-05-30 09:53:22 +02:00
self.tax_level = tax_level
self.period_seconds = period * 60
self.settings = DemurrageTokenSettings()
self.settings.name = token_name
self.settings.symbol = token_symbol
self.settings.decimals = 6
2023-02-10 11:05:10 +01:00
tax_level_input = to_fixed((1 - (tax_level / 1000000)) ** (1 / period))
self.settings.demurrage_level = tax_level_input
2022-05-30 09:53:22 +02:00
self.settings.period_minutes = period
self.settings.sink_address = sink_address
self.sink_address = self.settings.sink_address
2022-05-30 09:53:22 +02:00
logg.debug('using demurrage token settings: {}'.format(self.settings))
o = block_latest()
self.start_block = rpc.do(o)
o = block_by_number(self.start_block, include_tx=False)
r = rpc.do(o)
2021-06-05 08:45:37 +02:00
try:
self.start_time = int(r['timestamp'], 16)
except TypeError:
self.start_time = int(r['timestamp'])
2023-03-22 11:17:40 +01:00
def publish(self, rpc, publisher_address, interface, supply_cap=0):
2021-06-05 08:45:37 +02:00
tx_hash = None
o = None
2023-03-22 11:17:40 +01:00
(tx_hash, o) = interface.constructor(publisher_address, self.settings)
r = rpc.do(o)
o = receipt(tx_hash)
r = rpc.do(o)
assert r['status'] == 1
2021-06-05 08:45:37 +02:00
self.start_block = r['block_number']
self.address = r['contract_address']
2021-06-05 08:45:37 +02:00
o = block_by_number(r['block_number'])
r = rpc.do(o)
2021-06-05 08:45:37 +02:00
self.start_time = r['timestamp']
return self.address
class TestDemurrage(EthTesterCase):
def setUp(self):
super(TestDemurrage, self).setUp()
2022-05-30 09:53:22 +02:00
period = PERIOD
try:
period = getattr(self, 'period')
except AttributeError as e:
pass
2023-03-22 11:17:40 +01:00
self.publisher = TestTokenDeploy(self.rpc, period=period, sink_address=self.accounts[9])
2023-02-10 16:58:31 +01:00
self.default_supply = 0
self.default_supply_cap = 0
self.start_block = None
self.address = None
self.start_time = None
2023-03-22 11:17:40 +01:00
def publish(self, interface):
self.address = self.publisher.publish(self.rpc, self.accounts[0], interface, supply_cap=self.default_supply_cap)
self.start_block = self.publisher.start_block
self.start_time = self.publisher.start_time
self.tax_level = self.publisher.tax_level
self.period_seconds = self.publisher.period_seconds
self.sink_address = self.publisher.sink_address
logg.debug('contract address {} start block {} start time {}'.format(self.address, self.start_block, self.start_time))
2023-02-10 11:05:10 +01:00
def assert_within(self, v, target, tolerance_ppm):
lower_target = target - (target * (tolerance_ppm / 1000000))
higher_target = target + (target * (tolerance_ppm / 1000000))
#self.assertGreaterEqual(v, lower_target)
#self.assertLessEqual(v, higher_target)
if v >= lower_target and v <= higher_target:
logg.debug('asserted within {} <= {} <= {}'.format(lower_target, v, higher_target))
return
raise AssertionError('{} not within lower {} and higher {}'.format(v, lower_target, higher_target))
2023-03-22 11:17:40 +01:00
def assert_within_greater(self, v, target, tolerance_ppm):
greater_target = target + (target * (tolerance_ppm / 1000000))
self.assertLessEqual(v, greater_target)
self.assertGreaterEqual(v, target)
logg.debug('asserted within greater {} >= {} >= {}'.format(greater_target, v, target))
2021-06-08 11:53:51 +02:00
def assert_within_lower(self, v, target, tolerance_ppm):
lower_target = target - (target * (tolerance_ppm / 1000000))
self.assertGreaterEqual(v, lower_target)
self.assertLessEqual(v, target)
logg.debug('asserted within lower {} <= {} <= {}'.format(lower_target, v, target))
2023-02-10 11:05:10 +01:00
def assert_equal_decimals(self, v, target, precision):
target = int(target * (10 ** precision))
target = target / (10 ** precision)
self.assertEqual(v, target)
2023-02-04 15:41:40 +01:00
2021-06-05 08:45:37 +02:00
def tearDown(self):
pass
2021-06-05 08:45:37 +02:00
class TestDemurrageDefault(TestDemurrage):
def setUp(self):
super(TestDemurrageDefault, self).setUp()
nonce_oracle = RPCNonceOracle(self.accounts[0], self.rpc)
c = DemurrageToken(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle)
2023-03-22 11:17:40 +01:00
self.publish(c)
2023-02-10 16:58:31 +01:00
self.default_supply = 10**12
self.default_supply_cap = self.default_supply