erc20-demurrage-token

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

commit 399e24764aee27b277bebd28c2dfc88b6b7098fd
parent b7072fc50c007b0ab0c325b6fbfa26c829aea608
Author: nolash <dev@holbrook.no>
Date:   Sun,  6 Jun 2021 11:52:36 +0200

Remove redistribute calls on no redistribute sim

Diffstat:
Mpython/erc20_demurrage_token/sim/sim.py | 18++++++++++--------
Mpython/examples/sim.py | 2+-
Apython/examples/sim_noredistribute.py | 76++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mpython/tests/base.py | 48------------------------------------------------
Mpython/tests/test_redistribution.py | 11++++++++++-
5 files changed, 97 insertions(+), 58 deletions(-)

diff --git a/python/erc20_demurrage_token/sim/sim.py b/python/erc20_demurrage_token/sim/sim.py @@ -39,6 +39,7 @@ class DemurrageTokenSimulation: def __init__(self, chain_str, settings, redistribute=True, cap=0, actors=1): self.chain_spec = ChainSpec.from_chain_str(chain_str) self.accounts = [] + self.redistribute = redistribute self.keystore = DictKeystore() self.signer = EIP155Signer(self.keystore) self.eth_helper = create_tester_signer(self.keystore) @@ -220,22 +221,23 @@ class DemurrageTokenSimulation: self.last_block = r['number'] block_base = self.last_block - 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.change_period(self.address, self.accounts[2]) self.rpc.do(o) - for actor in self.actors: - nonce_oracle = RPCNonceOracle(actor, conn=self.rpc) + if self.redistribute: + 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, actor, actor) + (tx_hash, o) = c.apply_redistribution_on_account(self.address, self.sink_address, self.sink_address) 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() o = block_latest() diff --git a/python/examples/sim.py b/python/examples/sim.py @@ -45,7 +45,7 @@ sim.next() 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))) - +print('sink balance: demurraged {:>9d} base {:>9d}'.format(sim.balance(sim.sink_address), sim.balance(sim.sink_address, base=True))) # get times minutes = sim.get_minutes() diff --git a/python/examples/sim_noredistribute.py b/python/examples/sim_noredistribute.py @@ -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 = (10 ** 6) * (10 ** 12) + +# instantiate simulation +sim = DemurrageTokenSimulation(chain, settings, redistribute=False, 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))) +print('sink balance: demurraged {:>9d} base {:>9d}'.format(sim.balance(sim.sink_address), sim.balance(sim.sink_address, 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)) diff --git a/python/tests/base.py b/python/tests/base.py @@ -163,51 +163,3 @@ 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)) - diff --git a/python/tests/test_redistribution.py b/python/tests/test_redistribution.py @@ -8,7 +8,10 @@ import logging from chainlib.eth.constant import ZERO_ADDRESS from chainlib.eth.nonce import RPCNonceOracle from chainlib.eth.tx import receipt -from chainlib.eth.block import block_latest +from chainlib.eth.block import ( + block_latest, + block_by_number, + ) from chainlib.eth.address import to_checksum_address from hexathon import ( strip_0x, @@ -54,6 +57,12 @@ class TestRedistribution(TestDemurrageDefault): self.assertEqual(r['status'], 1) self.backend.time_travel(self.start_time + self.period_seconds + 1) + + o = block_latest() + r = self.rpc.do(o) + o = block_by_number(r) + r = self.rpc.do(o) + self.assertEqual(r['timestamp'], self.start_time + self.period_seconds) (tx_hash, o) = c.change_period(self.address, self.accounts[1]) r = self.rpc.do(o)