mirror of
git://holbrook.no/erc20-demurrage-token
synced 2024-11-22 00:06:46 +01:00
Test precision loss of 2 bytes in demurrage store in redistribution data
This commit is contained in:
parent
030cfdfc97
commit
c3a6a692ed
File diff suppressed because one or more lines are too long
@ -17,9 +17,10 @@ settings.symbol = 'SIM'
|
||||
settings.decimals = 6
|
||||
settings.demurrage_level = int(decay_per_minute*(10**38))
|
||||
#settings.period_minutes = 1 # 1 week in minutes
|
||||
settings.period_minutes = 10
|
||||
settings.period_minutes = 60*24*7
|
||||
chain = 'evm:foochain:42'
|
||||
cap = (10 ** 6) * (10 ** 12)
|
||||
#cap = 0
|
||||
|
||||
# instantiate simulation
|
||||
sim = DemurrageTokenSimulation(chain, settings, redistribute=False, cap=cap, actors=10)
|
||||
|
@ -7,10 +7,16 @@ export PYTHONPATH=.
|
||||
#modes=(MultiNocap MultiCap SingleCap SingleNocap)
|
||||
modes=(SingleCap SingleNocap) # other contracts need to be updted
|
||||
for m in ${modes[@]}; do
|
||||
ERC20_DEMURRAGE_TOKEN_TEST_MODE=$m python tests/test_period.py
|
||||
ERC20_DEMURRAGE_TOKEN_TEST_MODE=$m python tests/test_basic.py
|
||||
ERC20_DEMURRAGE_TOKEN_TEST_MODE=$m python tests/test_growth.py
|
||||
ERC20_DEMURRAGE_TOKEN_TEST_MODE=$m python tests/test_amounts.py
|
||||
ERC20_DEMURRAGE_TOKEN_TEST_MODE=$m python tests/test_single.py
|
||||
done
|
||||
|
||||
modes=(SingleCap) # other contracts need to be updted
|
||||
for m in ${modes[@]}; do
|
||||
ERC20_DEMURRAGE_TOKEN_TEST_MODE=$m python tests/test_period.py
|
||||
ERC20_DEMURRAGE_TOKEN_TEST_MODE=$m python tests/test_redistribution_unit.py
|
||||
done
|
||||
|
||||
modes=(MultiCap SingleCap)
|
||||
@ -18,12 +24,6 @@ for m in ${modes[@]}; do
|
||||
ERC20_DEMURRAGE_TOKEN_TEST_MODE=$m python tests/test_cap.py
|
||||
done
|
||||
|
||||
modes=(SingleCap SingleNocap)
|
||||
for m in ${modes[@]}; do
|
||||
ERC20_DEMURRAGE_TOKEN_TEST_MODE=$m python tests/test_single.py
|
||||
ERC20_DEMURRAGE_TOKEN_TEST_MODE=$m python tests/test_redistribution_unit.py
|
||||
done
|
||||
|
||||
#modes=(MultiCap MultiNocap)
|
||||
#for m in ${modes[@]}; do
|
||||
# ERC20_DEMURRAGE_TOKEN_TEST_MODE=$m python tests/test_remainder.py
|
||||
|
@ -70,10 +70,10 @@ class TestPeriod(TestDemurrageDefault):
|
||||
# allow test code float rounding error to billionth
|
||||
modifier = (1 - (self.tax_level / 1000000)) ** (self.period_seconds / 60)
|
||||
modifier *= 10 ** 9
|
||||
modifier = int(modifier) * (10 ** (38 - 9))
|
||||
modifier = int(modifier) * (10 ** (28 - 9))
|
||||
|
||||
period /= (10 ** (38 - 9))
|
||||
period = int(period) * (10 ** (38 - 9))
|
||||
period /= (10 ** (28 - 9))
|
||||
period = int(period) * (10 ** (28 - 9))
|
||||
self.assertEqual(modifier, period)
|
||||
|
||||
self.backend.time_travel(self.start_time + self.period_seconds * 2)
|
||||
@ -96,10 +96,10 @@ class TestPeriod(TestDemurrageDefault):
|
||||
# allow test code float rounding error to billionth
|
||||
modifier = (1 - (self.tax_level / 1000000)) ** ((self.period_seconds * 2) / 60)
|
||||
modifier *= 10 ** 9
|
||||
modifier = int(modifier) * (10 ** (38 - 9))
|
||||
modifier = int(modifier) * (10 ** (28 - 9))
|
||||
|
||||
period /= (10 ** (38 - 9))
|
||||
period = int(period) * (10 ** (38 - 9))
|
||||
period /= (10 ** (28 - 9))
|
||||
period = int(period) * (10 ** (28 - 9))
|
||||
self.assertEqual(modifier, period)
|
||||
|
||||
|
||||
|
@ -36,21 +36,23 @@ class TestRedistribution(TestDemurrageUnit):
|
||||
nonce_oracle = RPCNonceOracle(self.accounts[0], self.rpc)
|
||||
c = DemurrageToken(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle)
|
||||
|
||||
demurrage = (1 - (self.tax_level / 1000000)) * (10**38)
|
||||
#demurrage = (1 - (self.tax_level / 1000000)) * (10**38)
|
||||
demurrage = (1 - (self.tax_level / 1000000)) * (10**28)
|
||||
supply = self.default_supply
|
||||
|
||||
o = c.get_distribution(self.address, supply, demurrage, sender_address=self.accounts[0])
|
||||
r = self.rpc.do(o)
|
||||
distribution = c.parse_get_distribution(r)
|
||||
expected_distribution = self.default_supply * (self.tax_level / 1000000)
|
||||
self.assertEqual(distribution, expected_distribution)
|
||||
self.assert_within_lower(distribution, expected_distribution, 1000)
|
||||
|
||||
|
||||
def test_distribution_from_redistribution(self):
|
||||
nonce_oracle = RPCNonceOracle(self.accounts[0], self.rpc)
|
||||
c = DemurrageToken(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle)
|
||||
|
||||
demurrage = (1 - (self.tax_level / 1000000)) * (10**38)
|
||||
#demurrage = (1 - (self.tax_level / 1000000)) * (10**38)
|
||||
demurrage = (1 - (self.tax_level / 1000000)) * (10**28)
|
||||
supply = self.default_supply
|
||||
|
||||
o = c.to_redistribution(self.address, 0, demurrage, supply, 1, sender_address=self.accounts[0])
|
||||
@ -60,8 +62,7 @@ class TestRedistribution(TestDemurrageUnit):
|
||||
r = self.rpc.do(o)
|
||||
distribution = c.parse_get_distribution(r)
|
||||
expected_distribution = self.default_supply * (self.tax_level / 1000000)
|
||||
self.assertEqual(distribution, expected_distribution)
|
||||
|
||||
self.assert_within_lower(distribution, expected_distribution, 1000)
|
||||
|
||||
|
||||
def test_single_step(self):
|
||||
|
@ -12,7 +12,7 @@ contract DemurrageTokenSingleCap {
|
||||
uint8 constant shiftRedistributionValue = 32;
|
||||
uint256 constant maskRedistributionValue = 0x00000000000000000000000000000000000000ffffffffffffffffff00000000; // ((1 << 72) - 1) << 32
|
||||
uint8 constant shiftRedistributionDemurrage = 104;
|
||||
uint256 constant maskRedistributionDemurrage = 0x000000ffffffffffffffffffffffffffffffff00000000000000000000000000; // ((1 << 20) - 1) << 140
|
||||
uint256 constant maskRedistributionDemurrage = 0x0000000000ffffffffffffffffffffffffffff00000000000000000000000000; // ((1 << 20) - 1) << 140
|
||||
|
||||
// Account balances
|
||||
mapping (address => uint256) account;
|
||||
@ -115,7 +115,8 @@ contract DemurrageTokenSingleCap {
|
||||
periodStart = demurrageTimestamp;
|
||||
periodDuration = _periodMinutes * 60;
|
||||
//demurrageAmount = 100000000000000000000000000000000000000 - _taxLevelMinute; // Represents 38 decimal places, same as resolutionFactor
|
||||
demurrageAmount = 100000000000000000000000000000000000000;
|
||||
//demurrageAmount = 100000000000000000000000000000000000000;
|
||||
demurrageAmount = 10000000000000000000000000000;
|
||||
//demurragePeriod = 1;
|
||||
taxLevel = _taxLevelMinute; // Represents 38 decimal places
|
||||
bytes32 initialRedistribution = toRedistribution(0, demurrageAmount, 0, 1);
|
||||
@ -152,7 +153,7 @@ contract DemurrageTokenSingleCap {
|
||||
//periodCount = actualPeriod() - demurragePeriod;
|
||||
periodCount = getMinutesDelta(demurrageTimestamp);
|
||||
|
||||
currentDemurragedAmount = uint128(decayBy(demurrageAmount, periodCount));
|
||||
currentDemurragedAmount = uint128(decayBy(demurrageAmount * 10000000000, periodCount));
|
||||
|
||||
return (baseBalance * currentDemurragedAmount) / (nanoDivider * 1000000000000);
|
||||
}
|
||||
@ -281,7 +282,7 @@ contract DemurrageTokenSingleCap {
|
||||
function getDistribution(uint256 _supply, uint256 _demurrageAmount) public view returns (uint256) {
|
||||
uint256 difference;
|
||||
|
||||
difference = _supply * (resolutionFactor - _demurrageAmount); //(nanoDivider - ((resolutionFactor - _demurrageAmount) / nanoDivider));
|
||||
difference = _supply * (resolutionFactor - (_demurrageAmount * 10000000000)); //(nanoDivider - ((resolutionFactor - _demurrageAmount) / nanoDivider));
|
||||
return difference / resolutionFactor;
|
||||
}
|
||||
|
||||
@ -407,7 +408,7 @@ contract DemurrageTokenSingleCap {
|
||||
|
||||
// Inflates the given amount according to the current demurrage modifier
|
||||
function toBaseAmount(uint256 _value) public view returns (uint256) {
|
||||
return (_value * resolutionFactor) / demurrageAmount;
|
||||
return (_value * resolutionFactor) / (demurrageAmount * 10000000000);
|
||||
}
|
||||
|
||||
// Implements ERC20, triggers tax and/or redistribution
|
||||
|
@ -12,11 +12,7 @@ contract DemurrageTokenSingleCap {
|
||||
uint8 constant shiftRedistributionValue = 32;
|
||||
uint256 constant maskRedistributionValue = 0x00000000000000000000000000000000000000ffffffffffffffffff00000000; // ((1 << 72) - 1) << 32
|
||||
uint8 constant shiftRedistributionDemurrage = 104;
|
||||
uint256 constant maskRedistributionDemurrage = 0x000000ffffffffffffffffffffffffffffffff00000000000000000000000000; // ((1 << 20) - 1) << 140
|
||||
|
||||
uint8 constant shiftRedistributionIsUsed = 255;
|
||||
uint256 constant maskRedistributionIsUsed = 0x4000000000000000000000000000000000000000000000000000000000000000; // 1 << 255
|
||||
|
||||
uint256 constant maskRedistributionDemurrage = 0x0000000000ffffffffffffffffffffffffffff00000000000000000000000000; // ((1 << 20) - 1) << 140
|
||||
|
||||
// Account balances
|
||||
mapping (address => uint256) account;
|
||||
@ -116,7 +112,8 @@ contract DemurrageTokenSingleCap {
|
||||
periodStart = demurrageTimestamp;
|
||||
periodDuration = _periodMinutes * 60;
|
||||
//demurrageAmount = 100000000000000000000000000000000000000 - _taxLevelMinute; // Represents 38 decimal places, same as resolutionFactor
|
||||
demurrageAmount = 100000000000000000000000000000000000000;
|
||||
//demurrageAmount = 100000000000000000000000000000000000000;
|
||||
demurrageAmount = 10000000000000000000000000000;
|
||||
//demurragePeriod = 1;
|
||||
taxLevel = _taxLevelMinute; // Represents 38 decimal places
|
||||
bytes32 initialRedistribution = toRedistribution(0, demurrageAmount, 0, 1);
|
||||
@ -152,7 +149,8 @@ contract DemurrageTokenSingleCap {
|
||||
//periodCount = actualPeriod() - demurragePeriod;
|
||||
periodCount = getMinutesDelta(demurrageTimestamp);
|
||||
|
||||
currentDemurragedAmount = uint128(decayBy(demurrageAmount, periodCount));
|
||||
//currentDemurragedAmount = uint128(decayBy(demurrageAmount, periodCount));
|
||||
currentDemurragedAmount = uint128(decayBy(demurrageAmount * 10000000000, periodCount));
|
||||
|
||||
return (baseBalance * currentDemurragedAmount) / (nanoDivider * 1000000000000);
|
||||
}
|
||||
@ -406,7 +404,8 @@ contract DemurrageTokenSingleCap {
|
||||
|
||||
// Inflates the given amount according to the current demurrage modifier
|
||||
function toBaseAmount(uint256 _value) public view returns (uint256) {
|
||||
return (_value * resolutionFactor) / demurrageAmount;
|
||||
//return (_value * resolutionFactor) / demurrageAmount;
|
||||
return (_value * resolutionFactor) / (demurrageAmount * 10000000000);
|
||||
}
|
||||
|
||||
// Implements ERC20, triggers tax and/or redistribution
|
||||
|
Loading…
Reference in New Issue
Block a user