bug: Wrong redistribution amount + limited demurrage apply
This commit is contained in:
@@ -1,4 +1,7 @@
|
||||
- 0.0.2-pending
|
||||
- 0.0.9
|
||||
* Fix wrong redistribution calculation in single nocap
|
||||
[...]
|
||||
- 0.0.2
|
||||
* Move to chainlib-eth
|
||||
- 0.0.1-unreleased
|
||||
* Interface for redistributed and non-redistributed, with or without cap
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -325,8 +325,19 @@ class DemurrageToken(ERC20):
|
||||
return o
|
||||
|
||||
|
||||
def apply_demurrage(self, contract_address, sender_address):
|
||||
return self.transact_noarg('applyDemurrage', contract_address, sender_address)
|
||||
def apply_demurrage(self, contract_address, sender_address, limit=0, tx_format=TxFormat.JSONRPC):
|
||||
if limit == 0:
|
||||
return self.transact_noarg('applyDemurrage', contract_address, sender_address)
|
||||
|
||||
enc = ABIContractEncoder()
|
||||
enc.method('applyDemurrageLimited')
|
||||
enc.typ(ABIContractType.UINT256)
|
||||
enc.uint256(limit)
|
||||
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 change_period(self, contract_address, sender_address):
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
chainlib-eth~=0.0.15
|
||||
eth-erc20~=0.1.5
|
||||
funga-eth~=0.5.1
|
||||
chainlib-eth~=0.0.27
|
||||
eth-erc20~=0.1.10
|
||||
funga-eth~=0.5.6
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[metadata]
|
||||
name = erc20-demurrage-token
|
||||
version = 0.0.8
|
||||
version = 0.0.10
|
||||
description = ERC20 token with redistributed continual demurrage
|
||||
author = Louis Holbrook
|
||||
author_email = dev@holbrook.no
|
||||
|
||||
@@ -54,6 +54,32 @@ class TestBasic(TestDemurrageDefault):
|
||||
self.assertEqual(balance, 1024)
|
||||
|
||||
|
||||
def test_apply_demurrage_limited(self):
|
||||
modifier = (10 ** 28)
|
||||
|
||||
nonce_oracle = RPCNonceOracle(self.accounts[0], self.rpc)
|
||||
c = DemurrageToken(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle)
|
||||
|
||||
o = c.demurrage_amount(self.address, sender_address=self.accounts[0])
|
||||
r = self.rpc.do(o)
|
||||
demurrage_amount = c.parse_demurrage_amount(r)
|
||||
self.assertEqual(modifier, demurrage_amount)
|
||||
|
||||
self.backend.time_travel(self.start_time + 120)
|
||||
(tx_hash, o) = c.apply_demurrage(self.address, sender_address=self.accounts[0], limit=1)
|
||||
r = self.rpc.do(o)
|
||||
o = receipt(tx_hash)
|
||||
r = self.rpc.do(o)
|
||||
self.assertEqual(r['status'], 1)
|
||||
|
||||
o = c.demurrage_amount(self.address, sender_address=self.accounts[0])
|
||||
r = self.rpc.do(o)
|
||||
demurrage_amount = c.parse_demurrage_amount(r)
|
||||
modifier_base = 1000000 - self.tax_level
|
||||
modifier = int(modifier_base * (10 ** 22)) # 38 decimal places minus 6 (1000000)
|
||||
self.assertEqual(modifier, demurrage_amount)
|
||||
|
||||
|
||||
def test_apply_demurrage(self):
|
||||
modifier = (10 ** 28)
|
||||
|
||||
@@ -93,7 +119,6 @@ class TestBasic(TestDemurrageDefault):
|
||||
r = self.rpc.do(o)
|
||||
demurrage_amount = c.parse_demurrage_amount(r)
|
||||
modifier_base = 1000000 - self.tax_level
|
||||
logg.debug('modifier base {}'.format(modifier_base))
|
||||
modifier = int(modifier_base * (10 ** 22)) # 38 decimal places minus 6 (1000000)
|
||||
self.assertEqual(modifier, demurrage_amount)
|
||||
|
||||
@@ -107,10 +132,11 @@ class TestBasic(TestDemurrageDefault):
|
||||
r = self.rpc.do(o)
|
||||
demurrage_amount = c.parse_demurrage_amount(r)
|
||||
modifier_base = ((1000000 - self.tax_level) / 1000000) ** 10
|
||||
logg.warning('mod base {}'.format(modifier_base))
|
||||
modifier = int(modifier_base * (10 ** 12))
|
||||
|
||||
rounding_tolerance_nano = 4000000 # 0.000004% precision
|
||||
demurrage_amount_truncate = int(demurrage_amount / (10 ** 26)) # equals 12 decimal places
|
||||
demurrage_amount_truncate = int(demurrage_amount / (10 ** 16)) # equals 38 decimal places - 14 for the modifier magniture - 2 for percent int calc + 6 for token decimals <- TODO verify this calc
|
||||
self.assertGreaterEqual(modifier, demurrage_amount_truncate - rounding_tolerance_nano)
|
||||
self.assertLessEqual(modifier, demurrage_amount_truncate)
|
||||
|
||||
|
||||
@@ -7,7 +7,15 @@ import logging
|
||||
# external imports
|
||||
from chainlib.eth.constant import ZERO_ADDRESS
|
||||
from chainlib.eth.nonce import RPCNonceOracle
|
||||
from chainlib.eth.tx import receipt
|
||||
from chainlib.eth.tx import (
|
||||
receipt,
|
||||
TxFactory,
|
||||
TxFormat,
|
||||
)
|
||||
from chainlib.eth.contract import (
|
||||
ABIContractEncoder,
|
||||
ABIContractType,
|
||||
)
|
||||
|
||||
# local imports
|
||||
from erc20_demurrage_token import DemurrageToken
|
||||
@@ -103,5 +111,90 @@ class TestPeriod(TestDemurrageDefault):
|
||||
self.assertEqual(modifier, period)
|
||||
|
||||
|
||||
def test_change_sink(self):
|
||||
nonce_oracle = RPCNonceOracle(self.accounts[0], self.rpc)
|
||||
c = DemurrageToken(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle)
|
||||
|
||||
o = c.balance_of(self.address, ZERO_ADDRESS, sender_address=self.accounts[0])
|
||||
r = self.rpc.do(o)
|
||||
balance = c.parse_balance_of(r)
|
||||
self.assertEqual(balance, 0)
|
||||
|
||||
(tx_hash, o) = c.mint_to(self.address, self.accounts[0], self.accounts[1], 102400000000)
|
||||
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)
|
||||
|
||||
c = DemurrageToken(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle)
|
||||
(tx_hash, o) = c.change_period(self.address, self.accounts[0])
|
||||
r = self.rpc.do(o)
|
||||
o = receipt(tx_hash)
|
||||
r = self.rpc.do(o)
|
||||
self.assertEqual(r['status'], 1)
|
||||
|
||||
o = c.balance_of(self.address, ZERO_ADDRESS, sender_address=self.accounts[0])
|
||||
r = self.rpc.do(o)
|
||||
balance = c.parse_balance_of(r)
|
||||
self.assertGreater(balance, 0)
|
||||
old_sink_balance = balance
|
||||
|
||||
o = c.balance_of(self.address, self.accounts[3], sender_address=self.accounts[0])
|
||||
r = self.rpc.do(o)
|
||||
balance = c.parse_balance_of(r)
|
||||
self.assertEqual(balance, 0)
|
||||
|
||||
nonce_oracle = RPCNonceOracle(self.accounts[5], self.rpc)
|
||||
c = TxFactory(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle)
|
||||
enc = ABIContractEncoder()
|
||||
enc.method('setSinkAddress')
|
||||
enc.typ(ABIContractType.ADDRESS)
|
||||
enc.address(self.accounts[3])
|
||||
data = enc.get()
|
||||
o = c.template(self.accounts[5], self.address, use_nonce=True)
|
||||
o = c.set_code(o, data)
|
||||
(tx_hash, o) = c.finalize(o, TxFormat.JSONRPC)
|
||||
r = self.rpc.do(o)
|
||||
o = receipt(tx_hash)
|
||||
r = self.rpc.do(o)
|
||||
self.assertEqual(r['status'], 0)
|
||||
|
||||
nonce_oracle = RPCNonceOracle(self.accounts[0], self.rpc)
|
||||
c = TxFactory(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle)
|
||||
enc = ABIContractEncoder()
|
||||
enc.method('setSinkAddress')
|
||||
enc.typ(ABIContractType.ADDRESS)
|
||||
enc.address(self.accounts[3])
|
||||
data = enc.get()
|
||||
o = c.template(self.accounts[0], self.address, use_nonce=True)
|
||||
o = c.set_code(o, data)
|
||||
(tx_hash, o) = c.finalize(o, TxFormat.JSONRPC)
|
||||
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 * 2) + 1)
|
||||
|
||||
c = DemurrageToken(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle)
|
||||
(tx_hash, o) = c.change_period(self.address, self.accounts[0])
|
||||
r = self.rpc.do(o)
|
||||
o = receipt(tx_hash)
|
||||
r = self.rpc.do(o)
|
||||
self.assertEqual(r['status'], 1)
|
||||
|
||||
o = c.balance_of(self.address, ZERO_ADDRESS, sender_address=self.accounts[0])
|
||||
r = self.rpc.do(o)
|
||||
balance = c.parse_balance_of(r)
|
||||
self.assertLess(balance, old_sink_balance)
|
||||
|
||||
o = c.balance_of(self.address, self.accounts[3], sender_address=self.accounts[0])
|
||||
r = self.rpc.do(o)
|
||||
balance = c.parse_balance_of(r)
|
||||
self.assertGreater(balance, 0)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
Reference in New Issue
Block a user