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)