erc20-demurrage-token

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

commit f299e25dccf88e6e974a91108c2d821d7269a705
parent 4b780c81ad88731d79f85acc209ece3386cdefd1
Author: nolash <dev@holbrook.no>
Date:   Fri,  4 Jun 2021 15:08:03 +0200

Rehabilitate last test

Diffstat:
Mpython/erc20_demurrage_token/token.py | 42++++++++++++++++++++++++++++++++++++++++--
Mpython/tests/test_redistribution.py | 192+++++++++++++++++++++++++++++++++++++++++++++++++++----------------------------
2 files changed, 165 insertions(+), 69 deletions(-)

diff --git a/python/erc20_demurrage_token/token.py b/python/erc20_demurrage_token/token.py @@ -167,6 +167,21 @@ class DemurrageToken(ERC20): return o + def account_period(self, contract_address, address, sender_address=ZERO_ADDRESS): + o = jsonrpc_template() + o['method'] = 'eth_call' + enc = ABIContractEncoder() + enc.method('accountPeriod') + enc.typ(ABIContractType.ADDRESS) + enc.address(address) + 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_period(self, contract_address, redistribution, sender_address=ZERO_ADDRESS): o = jsonrpc_template() o['method'] = 'eth_call' @@ -190,6 +205,18 @@ class DemurrageToken(ERC20): return self.transact_noarg('changePeriod', contract_address, sender_address) + def apply_redistribution_on_account(self, contract_address, sender_address, address, tx_format=TxFormat.JSONRPC): + enc = ABIContractEncoder() + enc.method('applyRedistributionOnAccount') + enc.typ(ABIContractType.ADDRESS) + enc.address(address) + data = enc.get() + tx = self.template(sender_address, contract_address, use_nonce=True) + tx = self.set_code(tx, data) + tx = self.finalize(tx, tx_format) + return tx + + def actual_period(self, contract_address, sender_address=ZERO_ADDRESS): return self.call_noarg('actualPeriod', contract_address, sender_address=sender_address) @@ -206,35 +233,46 @@ class DemurrageToken(ERC20): return self.call_noarg('demurrageAmount', contract_address, sender_address=sender_address) + @classmethod def parse_actual_period(self, v): return abi_decode_single(ABIContractType.UINT256, v) + @classmethod def parse_period_start(self, v): return abi_decode_single(ABIContractType.UINT256, v) + @classmethod def parse_period_duration(self, v): return abi_decode_single(ABIContractType.UINT256, v) + @classmethod def parse_demurrage_amount(self, v): return abi_decode_single(ABIContractType.UINT256, v) + @classmethod def parse_remainder(self, v): return abi_decode_single(ABIContractType.UINT256, v) + @classmethod def parse_to_base_amount(self, v): return abi_decode_single(ABIContractType.UINT256, v) + @classmethod def parse_redistributions(self, v): return abi_decode_single(ABIContractType.BYTES32, v) - def parse_to_redistribution_period(self, v): - return abi_decode_single(ABIContractType.UINT256, v) + @classmethod + def parse_account_period(self, v): + return abi_decode_single(ABIContractType.ADDRESS, v) + @classmethod + def parse_to_redistribution_period(self, v): + return abi_decode_single(ABIContractType.UINT256, v) diff --git a/python/tests/test_redistribution.py b/python/tests/test_redistribution.py @@ -34,6 +34,7 @@ PERIOD = 1 class TestRedistribution(TestDemurrageDefault): + @unittest.skip('foo') def test_debug_periods(self): nonce_oracle = RPCNonceOracle(self.accounts[0], self.rpc) c = DemurrageToken(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) @@ -57,6 +58,7 @@ class TestRedistribution(TestDemurrageDefault): # TODO: check receipt log outputs + @unittest.skip('foo') def test_redistribution_storage(self): nonce_oracle = RPCNonceOracle(self.accounts[0], self.rpc) c = DemurrageToken(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) @@ -103,6 +105,7 @@ class TestRedistribution(TestDemurrageDefault): self.assertEqual(strip_0x(r), '000000000000000000000000ef4200000000000000000000002dc6c000000002') + @unittest.skip('foo') def test_redistribution_balance_on_zero_participants(self): supply = 1000000000000 @@ -118,14 +121,15 @@ class TestRedistribution(TestDemurrageDefault): (tx_hash, o) = c.change_period(self.address, self.accounts[0]) self.rpc.do(o) -# tx_hash = self.contract.functions.changePeriod().transact() -# rr = self.w3.eth.getTransactionReceipt(tx_hash) -# self.assertEqual(rr.status, 1) -# -# redistribution = self.contract.functions.redistributions(0).call(); -# supply = self.contract.functions.totalSupply().call() -# -# sink_increment = int(supply * (TAX_LEVEL / 1000000)) + o = c.redistributions(self.address, 0, sender_address=self.accounts[0]) + r = self.rpc.do(o) + redistributions = c.parse_redistributions(r) + + o = c.total_supply(self.address, sender_address=self.accounts[0]) + r = self.rpc.do(o) + supply = c.parse_total_supply(r) + + sink_increment = int(supply * (TAX_LEVEL / 1000000)) # for l in r['logs']: # if l.topics[0].hex() == '0xa0717e54e02bd9829db5e6e998aec0ae9de796b8d150a3cc46a92ab869697755': # event Decayed(uint256,uint256,uint256,uint256) # period = int.from_bytes(l.topics[1], 'big') @@ -143,66 +147,120 @@ class TestRedistribution(TestDemurrageDefault): # balance = self.contract.functions.balanceOf(self.w3.eth.accounts[1]).call() # self.assertEqual(balance, supply - sink_increment) # -# -# def test_redistribution_two_of_ten(self): -# mint_amount = 100000000 -# z = 0 -# for i in range(10): -# self.contract.functions.mintTo(self.w3.eth.accounts[i], mint_amount).transact() -# z += mint_amount -# -# initial_balance = self.contract.functions.balanceOf(self.w3.eth.accounts[1]).call() -# -# spend_amount = 1000000 -# external_address = web3.Web3.toChecksumAddress('0x' + os.urandom(20).hex()) -# self.contract.functions.transfer(external_address, spend_amount).transact({'from': self.w3.eth.accounts[1]}) -# tx_hash = self.contract.functions.transfer(external_address, spend_amount).transact({'from': self.w3.eth.accounts[2]}) -# r = self.w3.eth.getTransactionReceipt(tx_hash) -# # No cheating! -# self.contract.functions.transfer(self.w3.eth.accounts[3], spend_amount).transact({'from': self.w3.eth.accounts[3]}) -# # No cheapskating! -# self.contract.functions.transfer(external_address, spend_amount-1).transact({'from': self.w3.eth.accounts[4]}) -# -# self.assertEqual(r.status, 1) -# -# self.eth_tester.time_travel(self.start_time + 61) -# -# self.contract.functions.applyDemurrage().transact() -# self.contract.functions.changePeriod().transact() -# -# bummer_balance = self.contract.functions.balanceOf(self.w3.eth.accounts[3]).call() -# self.assertEqual(bummer_balance, mint_amount - (mint_amount * (TAX_LEVEL / 1000000))) -# logg.debug('bal {} '.format(bummer_balance)) -# -# bummer_balance = self.contract.functions.balanceOf(self.w3.eth.accounts[1]).call() -# spender_balance = mint_amount - spend_amount -# spender_decayed_balance = int(spender_balance - (spender_balance * (TAX_LEVEL / 1000000))) -# self.assertEqual(bummer_balance, spender_decayed_balance) -# logg.debug('bal {} '.format(bummer_balance)) -# -# tx_hash = self.contract.functions.applyRedistributionOnAccount(self.w3.eth.accounts[1]).transact() -# r = self.w3.eth.getTransactionReceipt(tx_hash) + + def test_redistribution_two_of_ten(self): + mint_amount = 100000000 + nonce_oracle = RPCNonceOracle(self.accounts[0], self.rpc) + c = DemurrageToken(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) + z = 0 + for i in range(10): + (tx_hash, o) = c.mint_to(self.address, self.accounts[0], self.accounts[i], mint_amount) + self.rpc.do(o) + z += mint_amount + + o = c.balance_of(self.address, self.accounts[1], sender_address=self.accounts[0]) + r = self.rpc.do(o) + initial_balance = c.parse_balance_of(r) + + spend_amount = 1000000 + external_address = to_checksum_address('0x' + os.urandom(20).hex()) + + 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], external_address, spend_amount) + self.rpc.do(o) + o = receipt(tx_hash) + r = self.rpc.do(o) + self.assertEqual(r['status'], 1) + + nonce_oracle = RPCNonceOracle(self.accounts[2], self.rpc) + c = DemurrageToken(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) + (tx_hash, o) = c.transfer(self.address, self.accounts[2], external_address, spend_amount) + self.rpc.do(o) + o = receipt(tx_hash) + r = self.rpc.do(o) + self.assertEqual(r['status'], 1) + + # No cheating! + nonce_oracle = RPCNonceOracle(self.accounts[3], self.rpc) + c = DemurrageToken(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) + (tx_hash, o) = c.transfer(self.address, self.accounts[3], self.accounts[3], spend_amount) + self.rpc.do(o) + o = receipt(tx_hash) + r = self.rpc.do(o) + self.assertEqual(r['status'], 1) + + # No cheapskating! + nonce_oracle = RPCNonceOracle(self.accounts[4], self.rpc) + c = DemurrageToken(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) + (tx_hash, o) = c.transfer(self.address, self.accounts[4], external_address, spend_amount-1) + 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 + 61) + + (tx_hash, o) = c.apply_demurrage(self.address, self.accounts[4]) + self.rpc.do(o) + + (tx_hash, o) = c.change_period(self.address, self.accounts[4]) + self.rpc.do(o) + + o = c.balance_of(self.address, self.accounts[3], sender_address=self.accounts[0]) + r = self.rpc.do(o) + bummer_balance = c.parse_balance_of(r) + + self.assertEqual(bummer_balance, mint_amount - (mint_amount * (TAX_LEVEL / 1000000))) + logg.debug('bal {} '.format(bummer_balance)) + + o = c.balance_of(self.address, self.accounts[1], sender_address=self.accounts[0]) + r = self.rpc.do(o) + bummer_balance = c.parse_balance_of(r) + spender_balance = mint_amount - spend_amount + spender_decayed_balance = int(spender_balance - (spender_balance * (TAX_LEVEL / 1000000))) + self.assertEqual(bummer_balance, spender_decayed_balance) + logg.debug('bal {} '.format(bummer_balance)) + + (tx_hash, o) = c.apply_redistribution_on_account(self.address, self.accounts[4], self.accounts[1]) + self.rpc.do(o) + o = receipt(tx_hash) + r = self.rpc.do(o) + self.assertEqual(r['status'], 1) + # logg.debug('log {}'.format(r.logs)) -# -# self.contract.functions.applyRedistributionOnAccount(self.w3.eth.accounts[2]).transact() -# -# redistribution_data = self.contract.functions.redistributions(0).call() -# logg.debug('redist data {}'.format(redistribution_data.hex())) -# -# account_period_data = self.contract.functions.accountPeriod(self.w3.eth.accounts[1]).call() -# logg.debug('account period {}'.format(account_period_data)) -# -# actual_period = self.contract.functions.actualPeriod().call() -# logg.debug('period {}'.format(actual_period)) -# -# redistribution = int((z / 2) * (TAX_LEVEL / 1000000)) -# spender_new_base_balance = ((mint_amount - spend_amount) + redistribution) -# spender_new_decayed_balance = int(spender_new_base_balance - (spender_new_base_balance * (TAX_LEVEL / 1000000))) -# -# spender_actual_balance = self.contract.functions.balanceOf(self.w3.eth.accounts[1]).call() -# logg.debug('rrr {} {}'.format(redistribution, spender_new_decayed_balance)) -# -# self.assertEqual(spender_actual_balance, spender_new_decayed_balance) + (tx_hash, o) = c.apply_redistribution_on_account(self.address, self.accounts[4], self.accounts[2]) + self.rpc.do(o) + o = receipt(tx_hash) + r = self.rpc.do(o) + self.assertEqual(r['status'], 1) + + o = c.redistributions(self.address, 0, sender_address=self.accounts[0]) + r = self.rpc.do(o) + redistribution_data = c.parse_redistributions(r) + logg.debug('redist data {}'.format(redistribution_data)) + + o = c.account_period(self.address, self.accounts[1], sender_address=self.accounts[0]) + r = self.rpc.do(o) + account_period_data = c.parse_account_period(r) + logg.debug('account period {}'.format(account_period_data)) + + o = c.actual_period(self.address, sender_address=self.accounts[0]) + r = self.rpc.do(o) + actual_period = c.parse_actual_period(r) + logg.debug('period {}'.format(actual_period)) + + redistribution = int((z / 2) * (TAX_LEVEL / 1000000)) + spender_new_base_balance = ((mint_amount - spend_amount) + redistribution) + spender_new_decayed_balance = int(spender_new_base_balance - (spender_new_base_balance * (TAX_LEVEL / 1000000))) + + o = c.balance_of(self.address, self.accounts[1], sender_address=self.accounts[0]) + r = self.rpc.do(o) + spender_actual_balance = c.parse_balance_of(r) + logg.debug('rrr {} {}'.format(redistribution, spender_new_decayed_balance)) + + self.assertEqual(spender_actual_balance, spender_new_decayed_balance) if __name__ == '__main__':