erc20-demurrage-token

ERC20 token with redistributed continual demurrage
Info | Log | Files | Refs | README

newbase.py (4854B)


      1 # standard imports
      2 import logging
      3 import os
      4 import math
      5 
      6 # external imports
      7 from chainlib.eth.unittest.ethtester import EthTesterCase
      8 from chainlib.eth.tx import (
      9         receipt,
     10         )
     11 from chainlib.eth.block import (
     12         block_latest,
     13         block_by_number,
     14         )
     15 from chainlib.eth.nonce import RPCNonceOracle
     16 from chainlib.eth.constant import ZERO_ADDRESS
     17 
     18 # local imports
     19 from erc20_demurrage_token import (
     20         DemurrageTokenSettings,
     21         DemurrageToken,
     22         )
     23 from dexif import *
     24 
     25 logg = logging.getLogger()
     26 
     27 TAX_LEVEL = int(10000 * 2) # 2%
     28 PERIOD = 43200 # 30 days in minutes
     29 
     30 class TestTokenDeploy:
     31 
     32     """tax level is ppm, 1000000 = 100%"""
     33     def __init__(self, rpc, token_symbol='FOO', token_name='Foo Token', sink_address=ZERO_ADDRESS, supply=10**12, tax_level=TAX_LEVEL, period=PERIOD):
     34         self.tax_level = tax_level
     35         self.period_seconds = period * 60
     36 
     37         self.settings = DemurrageTokenSettings()
     38         self.settings.name = token_name
     39         self.settings.symbol = token_symbol
     40         self.settings.decimals = 6
     41         tax_level_input = to_fixed((1 - (tax_level / 1000000)) ** (1 / period))
     42         self.settings.demurrage_level = tax_level_input
     43         self.settings.period_minutes = period
     44         self.settings.sink_address = sink_address
     45         self.sink_address = self.settings.sink_address
     46         logg.debug('using demurrage token settings: {}'.format(self.settings))
     47 
     48         o = block_latest()
     49         self.start_block = rpc.do(o)
     50         
     51         o = block_by_number(self.start_block, include_tx=False)
     52         r = rpc.do(o)
     53 
     54         try:
     55             self.start_time = int(r['timestamp'], 16)
     56         except TypeError:
     57             self.start_time = int(r['timestamp'])
     58 
     59         self.default_supply = supply
     60         self.default_supply_cap = 0
     61 
     62 
     63     def deploy(self, rpc, deployer_address, interface, supply_cap=0):
     64         tx_hash = None
     65         o = None
     66         (tx_hash, o) = interface.constructor(deployer_address, self.settings, redistribute=False, cap=0)
     67 
     68         r = rpc.do(o)
     69         o = receipt(tx_hash)
     70         r = rpc.do(o)
     71         assert r['status'] == 1
     72         self.start_block = r['block_number']
     73         self.address = r['contract_address']
     74 
     75         o = block_by_number(r['block_number'])
     76         r = rpc.do(o)
     77         self.start_time = r['timestamp']
     78 
     79         return self.address
     80 
     81 
     82 class TestDemurrage(EthTesterCase):
     83 
     84     def setUp(self):
     85         super(TestDemurrage, self).setUp()
     86         period = PERIOD
     87         try:
     88             period = getattr(self, 'period')
     89         except AttributeError as e:
     90             pass
     91         self.deployer = TestTokenDeploy(self.rpc, period=period)
     92         self.default_supply = self.deployer.default_supply
     93         self.default_supply_cap = self.deployer.default_supply_cap
     94         self.start_block = None
     95         self.address = None
     96         self.start_time = None
     97 
     98 
     99     def deploy(self, interface):
    100         self.address = self.deployer.deploy(self.rpc, self.accounts[0], interface, supply_cap=self.default_supply_cap)
    101         self.start_block = self.deployer.start_block
    102         self.start_time = self.deployer.start_time
    103         self.tax_level = self.deployer.tax_level
    104         self.period_seconds = self.deployer.period_seconds
    105         self.sink_address = self.deployer.sink_address
    106 
    107         logg.debug('contract address {} start block {} start time {}'.format(self.address, self.start_block, self.start_time))
    108 
    109 
    110     def assert_within(self, v, target, tolerance_ppm):
    111         lower_target = target - (target * (tolerance_ppm / 1000000))
    112         higher_target = target + (target * (tolerance_ppm / 1000000))
    113         #self.assertGreaterEqual(v, lower_target)
    114         #self.assertLessEqual(v, higher_target)
    115         if v >= lower_target and v <= higher_target:
    116             logg.debug('asserted within {} <= {} <= {}'.format(lower_target, v, higher_target))
    117             return
    118         raise AssertionError('{} not within lower {} and higher {}'.format(v, lower_target, higher_target))
    119 
    120 
    121     def assert_within_lower(self, v, target, tolerance_ppm):
    122         lower_target = target - (target * (tolerance_ppm / 1000000))
    123         self.assertGreaterEqual(v, lower_target)
    124         self.assertLessEqual(v, target)
    125         logg.debug('asserted within lower {} <= {} <= {}'.format(lower_target, v, target))
    126 
    127 
    128     def assert_equal_decimals(self, v, target, precision):
    129         target = int(target * (10 ** precision))
    130         target = target / (10 ** precision)
    131         self.assertEqual(v, target)
    132 
    133 
    134     def tearDown(self):
    135         pass
    136 
    137 
    138 class TestDemurrageDefault(TestDemurrage):
    139 
    140     def setUp(self):
    141         super(TestDemurrageDefault, self).setUp()
    142    
    143         nonce_oracle = RPCNonceOracle(self.accounts[0], self.rpc)
    144         c = DemurrageToken(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle)
    145 
    146         self.deploy(c)