mirror of
git://holbrook.no/erc20-demurrage-token
synced 2024-11-25 17:26:45 +01:00
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 = 1
|
||||||
self.period_txs = []
|
self.period_txs = []
|
||||||
self.period_tx_limit = self.period_seconds - 1
|
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(
|
logg.info('intialized at block {} timestamp {} period {} demurrage level {} sink address {} (first address in keystore)'.format(
|
||||||
self.last_block,
|
self.last_block,
|
||||||
@ -126,6 +127,32 @@ class DemurrageTokenSimulation:
|
|||||||
logg.debug('tx {} block {} index {} verified'.format(tx_hash, self.last_block, rcpt['transaction_index']))
|
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):
|
def from_units(self, v):
|
||||||
return v * (10 ** self.decimals)
|
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)
|
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)
|
(tx_hash, o) = c.mint_to(self.address, self.accounts[0], recipient, value)
|
||||||
self.rpc.do(o)
|
self.rpc.do(o)
|
||||||
self.next_block()
|
self.__next_block()
|
||||||
self.__check_tx(tx_hash)
|
self.__check_tx(tx_hash)
|
||||||
self.period_txs.append(tx_hash)
|
self.period_txs.append(tx_hash)
|
||||||
|
logg.info('mint {} tokens to {} - {}'.format(value, recipient, tx_hash))
|
||||||
return 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)
|
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)
|
(tx_hash, o) = c.transfer(self.address, sender, recipient, value)
|
||||||
self.rpc.do(o)
|
self.rpc.do(o)
|
||||||
self.next_block()
|
self.__next_block()
|
||||||
self.__check_tx(tx_hash)
|
self.__check_tx(tx_hash)
|
||||||
self.period_txs.append(tx_hash)
|
self.period_txs.append(tx_hash)
|
||||||
|
logg.info('transfer {} tokens from {} to {} - {}'.format(value, sender, recipient, tx_hash))
|
||||||
return tx_hash
|
return tx_hash
|
||||||
|
|
||||||
|
|
||||||
@ -163,42 +192,51 @@ class DemurrageTokenSimulation:
|
|||||||
return self.caller_contract.parse_balance_of(r)
|
return self.caller_contract.parse_balance_of(r)
|
||||||
|
|
||||||
|
|
||||||
def next_block(self):
|
def __next_block(self):
|
||||||
hsh = self.eth_helper.mine_block()
|
hsh = self.eth_helper.mine_block()
|
||||||
o = block_by_hash(hsh)
|
o = block_by_hash(hsh)
|
||||||
r = self.rpc.do(o)
|
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):
|
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))
|
logg.debug('warping to {}, {} from start'.format(target_timestamp, target_timestamp - self.start_timestamp))
|
||||||
self.last_timestamp = target_timestamp
|
self.last_timestamp = target_timestamp
|
||||||
|
|
||||||
self.eth_helper.time_travel(self.last_timestamp)
|
self.eth_helper.time_travel(self.last_timestamp)
|
||||||
self.next_block()
|
self.__next_block()
|
||||||
|
|
||||||
o = block_by_number(self.last_block)
|
o = block_by_number(self.last_block)
|
||||||
r = self.rpc.do(o)
|
r = self.rpc.do(o)
|
||||||
self.last_block = r['number']
|
self.last_block = r['number']
|
||||||
block_base = self.last_block
|
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)
|
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.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)
|
self.rpc.do(o)
|
||||||
self.next_block()
|
|
||||||
|
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()
|
||||||
|
|
||||||
o = block_latest()
|
o = block_latest()
|
||||||
self.last_block = self.rpc.do(o)
|
self.last_block = self.rpc.do(o)
|
||||||
@ -212,7 +250,7 @@ class DemurrageTokenSimulation:
|
|||||||
raise RuntimeError('demurrage step failed on block {}'.format(self.last_block))
|
raise RuntimeError('demurrage step failed on block {}'.format(self.last_block))
|
||||||
|
|
||||||
self.last_timestamp = r['timestamp']
|
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 += 1
|
||||||
self.period_txs = []
|
self.period_txs = []
|
||||||
|
|
||||||
|
@ -223,6 +223,51 @@ class DemurrageToken(ERC20):
|
|||||||
return o
|
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):
|
def base_balance_of(self, contract_address, address, sender_address=ZERO_ADDRESS):
|
||||||
o = jsonrpc_template()
|
o = jsonrpc_template()
|
||||||
o['method'] = 'eth_call'
|
o['method'] = 'eth_call'
|
||||||
@ -323,6 +368,11 @@ class DemurrageToken(ERC20):
|
|||||||
return abi_decode_single(ABIContractType.UINT256, v)
|
return abi_decode_single(ABIContractType.UINT256, v)
|
||||||
|
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def parse_to_redistribution_item(self, v):
|
||||||
|
return abi_decode_single(ABIContractType.UINT256, v)
|
||||||
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def parse_supply_cap(self, v):
|
def parse_supply_cap(self, v):
|
||||||
return abi_decode_single(ABIContractType.UINT256, 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)
|
self.deploy(c, self.mode)
|
||||||
|
|
||||||
logg.info('deployed with mode {}'.format(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()
|
self.sim.next()
|
||||||
|
|
||||||
balance = self.sim.balance(self.sim.actors[0])
|
balance = self.sim.balance(self.sim.actors[0])
|
||||||
self.assertEqual(balance, 89995500)
|
self.assertEqual(balance, 90005520)
|
||||||
|
|
||||||
balance = self.sim.balance(self.sim.actors[1])
|
balance = self.sim.balance(self.sim.actors[1])
|
||||||
self.assertEqual(balance, 99995000)
|
self.assertEqual(balance, 99995000)
|
||||||
|
@ -26,7 +26,6 @@ logg = logging.getLogger()
|
|||||||
|
|
||||||
testdir = os.path.dirname(__file__)
|
testdir = os.path.dirname(__file__)
|
||||||
|
|
||||||
|
|
||||||
class TestRedistribution(TestDemurrageDefault):
|
class TestRedistribution(TestDemurrageDefault):
|
||||||
|
|
||||||
def test_debug_periods(self):
|
def test_debug_periods(self):
|
||||||
@ -261,3 +260,5 @@ class TestRedistribution(TestDemurrageDefault):
|
|||||||
self.assertEqual(spender_actual_balance, spender_new_decayed_balance)
|
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;
|
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) {
|
function toRedistributionDemurrageModifier(bytes32 redistribution) public pure returns (uint256) {
|
||||||
return (uint256(redistribution) & maskRedistributionDemurrage) >> shiftRedistributionDemurrage;
|
return (uint256(redistribution) & maskRedistributionDemurrage) >> shiftRedistributionDemurrage;
|
||||||
}
|
}
|
||||||
@ -417,6 +417,8 @@ contract DemurrageTokenMultiCap {
|
|||||||
uint256 periodTimestamp;
|
uint256 periodTimestamp;
|
||||||
uint256 nextPeriod;
|
uint256 nextPeriod;
|
||||||
|
|
||||||
|
applyDemurrage();
|
||||||
|
|
||||||
currentRedistribution = checkPeriod();
|
currentRedistribution = checkPeriod();
|
||||||
if (currentRedistribution == bytes32(0x00)) {
|
if (currentRedistribution == bytes32(0x00)) {
|
||||||
return false;
|
return false;
|
||||||
@ -426,7 +428,7 @@ contract DemurrageTokenMultiCap {
|
|||||||
nextPeriod = currentPeriod + 1;
|
nextPeriod = currentPeriod + 1;
|
||||||
periodTimestamp = getPeriodTimeDelta(currentPeriod);
|
periodTimestamp = getPeriodTimeDelta(currentPeriod);
|
||||||
|
|
||||||
applyDemurrage();
|
//applyDemurrage();
|
||||||
currentDemurrageAmount = demurrageAmount;
|
currentDemurrageAmount = demurrageAmount;
|
||||||
|
|
||||||
demurrageCounts = demurrageCycles(periodTimestamp);
|
demurrageCounts = demurrageCycles(periodTimestamp);
|
||||||
|
Loading…
Reference in New Issue
Block a user