Introduce sim example
This commit is contained in:
		
							parent
							
								
									2f5bb63f9a
								
							
						
					
					
						commit
						c69d115965
					
				
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							@ -97,6 +97,7 @@ class DemurrageTokenSimulation:
 | 
			
		||||
        self.period = 1
 | 
			
		||||
        self.period_txs = []
 | 
			
		||||
        self.period_tx_limit = self.period_seconds - 1
 | 
			
		||||
        self.sink_address = settings.sink_address
 | 
			
		||||
 | 
			
		||||
        logg.info('intialized at block {} timestamp {} period {} demurrage level {} sink address {} (first address in keystore)'.format(
 | 
			
		||||
                self.last_block,
 | 
			
		||||
@ -126,6 +127,32 @@ class DemurrageTokenSimulation:
 | 
			
		||||
        logg.debug('tx {} block {} index {} verified'.format(tx_hash, self.last_block, rcpt['transaction_index']))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    def get_now(self):
 | 
			
		||||
        o = block_latest()
 | 
			
		||||
        r = self.rpc.do(o)
 | 
			
		||||
        o = block_by_number(r, include_tx=False)
 | 
			
		||||
        r = self.rpc.do(o)
 | 
			
		||||
        return r['timestamp']
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    def get_minutes(self):
 | 
			
		||||
        t = self.get_now()
 | 
			
		||||
        return int((t - self.start_timestamp) / 60)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    def get_start(self):
 | 
			
		||||
        return self.start_timestamp
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    def get_period(self):
 | 
			
		||||
        return self.period
 | 
			
		||||
 | 
			
		||||
    def get_demurrage_modifier(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))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    def from_units(self, v):
 | 
			
		||||
        return v * (10 ** self.decimals)
 | 
			
		||||
 | 
			
		||||
@ -136,9 +163,10 @@ class DemurrageTokenSimulation:
 | 
			
		||||
        c = DemurrageToken(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle, gas_oracle=self.gas_oracle)
 | 
			
		||||
        (tx_hash, o) = c.mint_to(self.address, self.accounts[0], recipient, value)
 | 
			
		||||
        self.rpc.do(o)
 | 
			
		||||
        self.next_block()
 | 
			
		||||
        self.__next_block()
 | 
			
		||||
        self.__check_tx(tx_hash)
 | 
			
		||||
        self.period_txs.append(tx_hash)
 | 
			
		||||
        logg.info('mint {} tokens to {} - {}'.format(value, recipient, tx_hash))
 | 
			
		||||
        return tx_hash
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -147,9 +175,10 @@ class DemurrageTokenSimulation:
 | 
			
		||||
        c = DemurrageToken(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle, gas_oracle=self.gas_oracle)
 | 
			
		||||
        (tx_hash, o) = c.transfer(self.address, sender, recipient, value)
 | 
			
		||||
        self.rpc.do(o)
 | 
			
		||||
        self.next_block()
 | 
			
		||||
        self.__next_block()
 | 
			
		||||
        self.__check_tx(tx_hash)
 | 
			
		||||
        self.period_txs.append(tx_hash)
 | 
			
		||||
        logg.info('transfer {} tokens from {} to {} - {}'.format(value, sender, recipient, tx_hash))
 | 
			
		||||
        return tx_hash
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -163,42 +192,51 @@ class DemurrageTokenSimulation:
 | 
			
		||||
        return self.caller_contract.parse_balance_of(r)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    def next_block(self):
 | 
			
		||||
    def __next_block(self):
 | 
			
		||||
        hsh = self.eth_helper.mine_block()
 | 
			
		||||
        o = block_by_hash(hsh)
 | 
			
		||||
        r = self.rpc.do(o)
 | 
			
		||||
        logg.info('now at block {} timestamp {}'.format(r['number'], r['timestamp']))
 | 
			
		||||
 | 
			
		||||
        for tx_hash in r['transactions']:
 | 
			
		||||
            o = receipt(tx_hash)
 | 
			
		||||
            rcpt = self.rpc.do(o)
 | 
			
		||||
            if rcpt['status'] == 0:
 | 
			
		||||
                raise RuntimeError('tx {} (block {} index {}) failed'.format(tx_hash, self.last_block, rcpt['transaction_index']))
 | 
			
		||||
            logg.debug('tx {} (block {} index {}) verified'.format(tx_hash, self.last_block, rcpt['transaction_index']))
 | 
			
		||||
 | 
			
		||||
        logg.debug('now at block {} timestamp {}'.format(r['number'], r['timestamp']))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    def next(self):
 | 
			
		||||
        target_timestamp = self.start_timestamp + (self.period * self.period_seconds) - 1
 | 
			
		||||
        target_timestamp = self.start_timestamp + (self.period * self.period_seconds)
 | 
			
		||||
        logg.debug('warping to {}, {} from start'.format(target_timestamp, target_timestamp - self.start_timestamp))
 | 
			
		||||
        self.last_timestamp = target_timestamp 
 | 
			
		||||
 | 
			
		||||
        self.eth_helper.time_travel(self.last_timestamp)
 | 
			
		||||
        self.next_block()
 | 
			
		||||
        self.__next_block()
 | 
			
		||||
 | 
			
		||||
        o = block_by_number(self.last_block)
 | 
			
		||||
        r = self.rpc.do(o)
 | 
			
		||||
        self.last_block = r['number']
 | 
			
		||||
        block_base = self.last_block
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
#        for tx_hash in r['transactions']:
 | 
			
		||||
#            o = receipt(tx_hash)
 | 
			
		||||
#            rcpt = self.rpc.do(o)
 | 
			
		||||
#            if rcpt['status'] == 0:
 | 
			
		||||
#                raise RuntimeError('tx {} (block {} index {}) failed'.format(tx_hash, self.last_block, rcpt['transaction_index']))
 | 
			
		||||
#            logg.info('tx {} (block {} index {}) verified'.format(tx_hash, self.last_block, rcpt['transaction_index']))
 | 
			
		||||
 | 
			
		||||
        nonce_oracle = RPCNonceOracle(self.accounts[0], conn=self.rpc)
 | 
			
		||||
        nonce_oracle = RPCNonceOracle(self.accounts[2], conn=self.rpc)
 | 
			
		||||
        c = DemurrageToken(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle, gas_oracle=self.gas_oracle)
 | 
			
		||||
        (tx_hash, o) = c.apply_demurrage(self.address, self.accounts[0])
 | 
			
		||||
        (tx_hash, o) = c.change_period(self.address, self.accounts[2])
 | 
			
		||||
        self.rpc.do(o)
 | 
			
		||||
        self.next_block()
 | 
			
		||||
 | 
			
		||||
        (tx_hash, o) = c.change_period(self.address, self.accounts[0])
 | 
			
		||||
        for actor in self.actors:
 | 
			
		||||
            nonce_oracle = RPCNonceOracle(actor, conn=self.rpc)
 | 
			
		||||
            c = DemurrageToken(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle, gas_oracle=self.gas_oracle)
 | 
			
		||||
            (tx_hash, o) = c.apply_redistribution_on_account(self.address, actor, actor)
 | 
			
		||||
            self.rpc.do(o)
 | 
			
		||||
 | 
			
		||||
        nonce_oracle = RPCNonceOracle(self.sink_address, conn=self.rpc)
 | 
			
		||||
        c = DemurrageToken(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle, gas_oracle=self.gas_oracle)
 | 
			
		||||
        (tx_hash, o) = c.apply_redistribution_on_account(self.address, self.sink_address, self.sink_address)
 | 
			
		||||
        self.rpc.do(o)
 | 
			
		||||
        self.next_block()
 | 
			
		||||
        self.__next_block()
 | 
			
		||||
 | 
			
		||||
        o = block_latest()
 | 
			
		||||
        self.last_block = self.rpc.do(o)
 | 
			
		||||
@ -212,7 +250,7 @@ class DemurrageTokenSimulation:
 | 
			
		||||
                raise RuntimeError('demurrage step failed on block {}'.format(self.last_block))
 | 
			
		||||
 | 
			
		||||
        self.last_timestamp = r['timestamp']
 | 
			
		||||
        logg.info('next concludes at block {} timestamp {}, {} after start'.format(self.last_block, self.last_timestamp, self.last_timestamp - self.start_timestamp))
 | 
			
		||||
        logg.debug('next concludes at block {} timestamp {}, {} after start'.format(self.last_block, self.last_timestamp, self.last_timestamp - self.start_timestamp))
 | 
			
		||||
        self.period += 1
 | 
			
		||||
        self.period_txs = []
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -223,6 +223,51 @@ class DemurrageToken(ERC20):
 | 
			
		||||
        return o
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    def to_redistribution_participants(self, contract_address, redistribution, sender_address=ZERO_ADDRESS):
 | 
			
		||||
        o = jsonrpc_template()
 | 
			
		||||
        o['method'] = 'eth_call'
 | 
			
		||||
        enc = ABIContractEncoder()
 | 
			
		||||
        enc.method('toRedistributionParticipants')
 | 
			
		||||
        enc.typ(ABIContractType.BYTES32)
 | 
			
		||||
        enc.bytes32(redistribution)
 | 
			
		||||
        data = add_0x(enc.get())
 | 
			
		||||
        tx = self.template(sender_address, contract_address)
 | 
			
		||||
        tx = self.set_code(tx, data)
 | 
			
		||||
        o['params'].append(self.normalize(tx))
 | 
			
		||||
        o['params'].append('latest')
 | 
			
		||||
        return o
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    def to_redistribution_supply(self, contract_address, redistribution, sender_address=ZERO_ADDRESS):
 | 
			
		||||
        o = jsonrpc_template()
 | 
			
		||||
        o['method'] = 'eth_call'
 | 
			
		||||
        enc = ABIContractEncoder()
 | 
			
		||||
        enc.method('toRedistributionSupply')
 | 
			
		||||
        enc.typ(ABIContractType.BYTES32)
 | 
			
		||||
        enc.bytes32(redistribution)
 | 
			
		||||
        data = add_0x(enc.get())
 | 
			
		||||
        tx = self.template(sender_address, contract_address)
 | 
			
		||||
        tx = self.set_code(tx, data)
 | 
			
		||||
        o['params'].append(self.normalize(tx))
 | 
			
		||||
        o['params'].append('latest')
 | 
			
		||||
        return o
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    def to_redistribution_demurrage_modifier(self, contract_address, redistribution, sender_address=ZERO_ADDRESS):
 | 
			
		||||
        o = jsonrpc_template()
 | 
			
		||||
        o['method'] = 'eth_call'
 | 
			
		||||
        enc = ABIContractEncoder()
 | 
			
		||||
        enc.method('toRedistributionDemurrageModifier')
 | 
			
		||||
        enc.typ(ABIContractType.BYTES32)
 | 
			
		||||
        enc.bytes32(redistribution)
 | 
			
		||||
        data = add_0x(enc.get())
 | 
			
		||||
        tx = self.template(sender_address, contract_address)
 | 
			
		||||
        tx = self.set_code(tx, data)
 | 
			
		||||
        o['params'].append(self.normalize(tx))
 | 
			
		||||
        o['params'].append('latest')
 | 
			
		||||
        return o
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    def base_balance_of(self, contract_address, address, sender_address=ZERO_ADDRESS):
 | 
			
		||||
        o = jsonrpc_template()
 | 
			
		||||
        o['method'] = 'eth_call'
 | 
			
		||||
@ -323,6 +368,11 @@ class DemurrageToken(ERC20):
 | 
			
		||||
        return abi_decode_single(ABIContractType.UINT256, v)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def parse_to_redistribution_item(self, v):
 | 
			
		||||
        return abi_decode_single(ABIContractType.UINT256, v)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def parse_supply_cap(self, v):
 | 
			
		||||
        return abi_decode_single(ABIContractType.UINT256, v)
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										76
									
								
								python/examples/sim.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								python/examples/sim.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,76 @@
 | 
			
		||||
# standard imports
 | 
			
		||||
import logging
 | 
			
		||||
 | 
			
		||||
# local imports
 | 
			
		||||
from erc20_demurrage_token import DemurrageTokenSettings
 | 
			
		||||
from erc20_demurrage_token.sim import DemurrageTokenSimulation
 | 
			
		||||
 | 
			
		||||
logging.basicConfig(level=logging.WARNING)
 | 
			
		||||
logg = logging.getLogger()
 | 
			
		||||
 | 
			
		||||
decay_per_minute = 0.000050105908373373 # equals approx 2% per month
 | 
			
		||||
 | 
			
		||||
# parameters for simulation object
 | 
			
		||||
settings = DemurrageTokenSettings()
 | 
			
		||||
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
 | 
			
		||||
chain = 'evm:foochain:42'
 | 
			
		||||
cap = sim.from_units(10 ** 12) # 1 tn token units, with 6 decimal places
 | 
			
		||||
 | 
			
		||||
# instantiate simulation
 | 
			
		||||
sim = DemurrageTokenSimulation(chain, settings, redistribute=True, cap=cap, actors=10)
 | 
			
		||||
 | 
			
		||||
# name the usual suspects
 | 
			
		||||
alice = sim.actors[0]
 | 
			
		||||
bob = sim.actors[1]
 | 
			
		||||
carol = sim.actors[2]
 | 
			
		||||
 | 
			
		||||
# mint and transfer (every single action advances one block, and one second in time)
 | 
			
		||||
sim.mint(alice, sim.from_units(100)) # 10000000 tokens
 | 
			
		||||
sim.mint(bob, sim.from_units(100))
 | 
			
		||||
sim.transfer(alice, carol, sim.from_units(50))
 | 
			
		||||
 | 
			
		||||
# check that balances have been updated
 | 
			
		||||
assert sim.balance(alice) == sim.from_units(50)
 | 
			
		||||
assert sim.balance(bob) == sim.from_units(100)
 | 
			
		||||
assert sim.balance(carol) == sim.from_units(50)
 | 
			
		||||
 | 
			
		||||
# advance to next redistribution period
 | 
			
		||||
sim.next()
 | 
			
		||||
 | 
			
		||||
# inspect balances
 | 
			
		||||
print('alice balance: demurraged {:>9d} base {:>9d}'.format(sim.balance(alice), sim.balance(alice, base=True)))
 | 
			
		||||
print('bob balance:   demurraged {:>9d} base {:>9d}'.format(sim.balance(bob), sim.balance(bob, base=True)))
 | 
			
		||||
print('carol balance: demurraged {:>9d} base {:>9d}'.format(sim.balance(carol), sim.balance(carol, base=True)))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# get times
 | 
			
		||||
minutes = sim.get_minutes()
 | 
			
		||||
start = sim.get_now()
 | 
			
		||||
timestamp = sim.get_start()
 | 
			
		||||
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)
 | 
			
		||||
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 {}
 | 
			
		||||
demurrage delta {}""".format(
 | 
			
		||||
    alice_checksum,
 | 
			
		||||
    sim.balance(alice),
 | 
			
		||||
    frontend_demurrage,
 | 
			
		||||
    contract_demurrage,
 | 
			
		||||
    demurrage_delta),
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
balance_sum = sim.balance(alice) + sim.balance(bob) + sim.balance(carol)
 | 
			
		||||
print('sum of contract demurraged balances {}'.format(balance_sum))
 | 
			
		||||
@ -163,3 +163,51 @@ class TestDemurrageCap(TestDemurrage):
 | 
			
		||||
        self.deploy(c, self.mode)
 | 
			
		||||
 | 
			
		||||
        logg.info('deployed with mode {}'.format(self.mode))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class TestDemurrageReal(TestDemurrage):
 | 
			
		||||
 | 
			
		||||
    def setUp(self):
 | 
			
		||||
        super(TestDemurrage, self).setUp()
 | 
			
		||||
 | 
			
		||||
        self.tax_level = int(0.000050105908373373*(10**40))
 | 
			
		||||
        self.period = 10800
 | 
			
		||||
        self.period_seconds = self.period * 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
 | 
			
		||||
        self.settings.period_minutes = 10800
 | 
			
		||||
        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')
 | 
			
		||||
        if self.mode == None:
 | 
			
		||||
            self.mode = 'MultiNocap'
 | 
			
		||||
        logg.debug('executing test setup default mode {}'.format(self.mode))
 | 
			
		||||
 | 
			
		||||
        self.deploy(c, self.mode)
 | 
			
		||||
 | 
			
		||||
        logg.info('deployed with mode {}'.format(self.mode))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -60,7 +60,7 @@ class TestSim(unittest.TestCase):
 | 
			
		||||
        self.sim.next()
 | 
			
		||||
 | 
			
		||||
        balance = self.sim.balance(self.sim.actors[0])
 | 
			
		||||
        self.assertEqual(balance, 89995500)
 | 
			
		||||
        self.assertEqual(balance, 90005520)
 | 
			
		||||
        
 | 
			
		||||
        balance = self.sim.balance(self.sim.actors[1])
 | 
			
		||||
        self.assertEqual(balance, 99995000)
 | 
			
		||||
 | 
			
		||||
@ -26,7 +26,6 @@ logg = logging.getLogger()
 | 
			
		||||
 | 
			
		||||
testdir = os.path.dirname(__file__)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class TestRedistribution(TestDemurrageDefault):
 | 
			
		||||
 | 
			
		||||
    def test_debug_periods(self):
 | 
			
		||||
@ -261,3 +260,5 @@ class TestRedistribution(TestDemurrageDefault):
 | 
			
		||||
        self.assertEqual(spender_actual_balance, spender_new_decayed_balance)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
if __name__ == '__main__':
 | 
			
		||||
    unittest.main()
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										84
									
								
								python/tests/test_redistribution_real.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								python/tests/test_redistribution_real.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,84 @@
 | 
			
		||||
# standard imports
 | 
			
		||||
import os
 | 
			
		||||
import unittest
 | 
			
		||||
import json
 | 
			
		||||
import logging
 | 
			
		||||
 | 
			
		||||
# external imports
 | 
			
		||||
from chainlib.eth.nonce import RPCNonceOracle
 | 
			
		||||
from chainlib.eth.tx import receipt
 | 
			
		||||
 | 
			
		||||
# local imports
 | 
			
		||||
from erc20_demurrage_token import DemurrageToken
 | 
			
		||||
 | 
			
		||||
# test imports
 | 
			
		||||
from tests.base import TestDemurrageReal
 | 
			
		||||
 | 
			
		||||
logging.basicConfig(level=logging.DEBUG)
 | 
			
		||||
logg = logging.getLogger()
 | 
			
		||||
 | 
			
		||||
testdir = os.path.dirname(__file__)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class TestRedistribution(TestDemurrageReal):
 | 
			
		||||
 | 
			
		||||
    def test_simple_example(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], 100000000)
 | 
			
		||||
        self.rpc.do(o)
 | 
			
		||||
        o = receipt(tx_hash)
 | 
			
		||||
        r = self.rpc.do(o)
 | 
			
		||||
        self.assertEqual(r['status'], 1)
 | 
			
		||||
        
 | 
			
		||||
        (tx_hash, o) = c.mint_to(self.address, self.accounts[0], self.accounts[2], 100000000)
 | 
			
		||||
        self.rpc.do(o)
 | 
			
		||||
        o = receipt(tx_hash)
 | 
			
		||||
        r = self.rpc.do(o)
 | 
			
		||||
        self.assertEqual(r['status'], 1)
 | 
			
		||||
        
 | 
			
		||||
        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], 50000000)
 | 
			
		||||
        r = self.rpc.do(o)
 | 
			
		||||
        o = receipt(tx_hash)
 | 
			
		||||
        r = self.rpc.do(o)
 | 
			
		||||
        self.assertEqual(r['status'], 1)
 | 
			
		||||
 | 
			
		||||
        self.backend.time_travel(self.start_time + self.period_seconds + 1)
 | 
			
		||||
 | 
			
		||||
        (tx_hash, o) = c.change_period(self.address, self.accounts[1])
 | 
			
		||||
        r = self.rpc.do(o)
 | 
			
		||||
        o = receipt(tx_hash)
 | 
			
		||||
        r = self.rpc.do(o)
 | 
			
		||||
        self.assertEqual(r['status'], 1)
 | 
			
		||||
 | 
			
		||||
        o = c.redistributions(self.address, 1, sender_address=self.accounts[0])
 | 
			
		||||
        redistribution = self.rpc.do(o)
 | 
			
		||||
        logg.debug('redistribution {}'.format(redistribution))
 | 
			
		||||
 | 
			
		||||
        o = c.to_redistribution_period(self.address, redistribution, sender_address=self.accounts[0])
 | 
			
		||||
        r = self.rpc.do(o)
 | 
			
		||||
        period = c.parse_to_redistribution_item(r)
 | 
			
		||||
        logg.debug('period {}'.format(period))
 | 
			
		||||
 | 
			
		||||
        o = c.to_redistribution_participants(self.address, redistribution, sender_address=self.accounts[0])
 | 
			
		||||
        r = self.rpc.do(o)
 | 
			
		||||
        participants = c.parse_to_redistribution_item(r)
 | 
			
		||||
        logg.debug('participants {}'.format(participants))
 | 
			
		||||
 | 
			
		||||
        o = c.to_redistribution_supply(self.address, redistribution, sender_address=self.accounts[0])
 | 
			
		||||
        r = self.rpc.do(o)
 | 
			
		||||
        supply = c.parse_to_redistribution_item(r)
 | 
			
		||||
        logg.debug('supply {}'.format(supply))
 | 
			
		||||
 | 
			
		||||
        o = c.to_redistribution_demurrage_modifier(self.address, redistribution, sender_address=self.accounts[0])
 | 
			
		||||
        r = self.rpc.do(o)
 | 
			
		||||
        modifier = c.parse_to_redistribution_item(r)
 | 
			
		||||
        logg.debug('modifier {}'.format(modifier))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
if __name__ == '__main__':
 | 
			
		||||
    unittest.main()
 | 
			
		||||
@ -246,7 +246,7 @@ contract DemurrageTokenMultiCap {
 | 
			
		||||
		return (uint256(redistribution) & maskRedistributionParticipants) >> shiftRedistributionParticipants;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Serializes the number of participants part of the redistribution word
 | 
			
		||||
	// Serializes the demurrage modifier part of the redistribution word
 | 
			
		||||
	function toRedistributionDemurrageModifier(bytes32 redistribution) public pure returns (uint256) {
 | 
			
		||||
		return (uint256(redistribution) & maskRedistributionDemurrage) >> shiftRedistributionDemurrage;
 | 
			
		||||
	}
 | 
			
		||||
@ -417,6 +417,8 @@ contract DemurrageTokenMultiCap {
 | 
			
		||||
		uint256 periodTimestamp;
 | 
			
		||||
		uint256 nextPeriod;
 | 
			
		||||
 | 
			
		||||
		applyDemurrage();
 | 
			
		||||
 | 
			
		||||
		currentRedistribution = checkPeriod();
 | 
			
		||||
		if (currentRedistribution == bytes32(0x00)) {
 | 
			
		||||
			return false;
 | 
			
		||||
@ -426,7 +428,7 @@ contract DemurrageTokenMultiCap {
 | 
			
		||||
		nextPeriod = currentPeriod + 1;
 | 
			
		||||
		periodTimestamp = getPeriodTimeDelta(currentPeriod);
 | 
			
		||||
 | 
			
		||||
		applyDemurrage();
 | 
			
		||||
		//applyDemurrage();
 | 
			
		||||
		currentDemurrageAmount = demurrageAmount; 
 | 
			
		||||
 | 
			
		||||
		demurrageCounts = demurrageCycles(periodTimestamp);
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user