Improve resolution in fractional calc in contract

This commit is contained in:
nolash 2021-06-07 17:49:22 +02:00
parent 5f69a1d7a1
commit 81ec2198aa
Signed by: lash
GPG Key ID: 21D2E7BB88C2A746
4 changed files with 25 additions and 10 deletions

File diff suppressed because one or more lines are too long

View File

@ -8,7 +8,7 @@ from erc20_demurrage_token.sim import DemurrageTokenSimulation
logging.basicConfig(level=logging.INFO) logging.basicConfig(level=logging.INFO)
logg = logging.getLogger() logg = logging.getLogger()
decay_per_minute = 0.00000050105908373373 # equals approx 2% per month decay_per_minute = 0.00050105908373373 # equals approx 2% per month
# parameters for simulation object # parameters for simulation object
settings = DemurrageTokenSettings() settings = DemurrageTokenSettings()
@ -17,7 +17,7 @@ settings.symbol = 'SIM'
settings.decimals = 6 settings.decimals = 6
settings.demurrage_level = int(decay_per_minute*(10**38)) settings.demurrage_level = int(decay_per_minute*(10**38))
#settings.period_minutes = 1 # 1 week in minutes #settings.period_minutes = 1 # 1 week in minutes
settings.period_minutes = 60*24*7*4 settings.period_minutes = 60*24*7
chain = 'evm:foochain:42' chain = 'evm:foochain:42'
cap = (10 ** 6) * (10 ** 12) cap = (10 ** 6) * (10 ** 12)

View File

@ -39,6 +39,21 @@ class TestBasic(TestDemurrageDefault):
r = self.rpc.do(o) r = self.rpc.do(o)
def test_balance(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], 1024)
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, self.accounts[1], sender_address=self.accounts[0])
r = self.rpc.do(o)
balance = c.parse_balance_of(r)
self.assertEqual(balance, 1024)
def test_apply_demurrage(self): def test_apply_demurrage(self):
modifier = 10 * (10 ** 37) modifier = 10 * (10 ** 37)

View File

@ -50,7 +50,7 @@ contract DemurrageTokenSingleCap {
// 128 bit resolution of the demurrage divisor // 128 bit resolution of the demurrage divisor
// (this constant x 1000000 is contained within 128 bits) // (this constant x 1000000 is contained within 128 bits)
uint256 constant ppmDivider = 100000000000000000000000000000000; uint256 constant ppmDivider = 100000000000000000000000000; // now nanodivider, 6 zeros less
// Timestamp of start of periods (time which contract constructor was called) // Timestamp of start of periods (time which contract constructor was called)
uint256 public immutable periodStart; uint256 public immutable periodStart;
@ -108,7 +108,7 @@ contract DemurrageTokenSingleCap {
demurrageTimestamp = block.timestamp; demurrageTimestamp = block.timestamp;
periodStart = demurrageTimestamp; periodStart = demurrageTimestamp;
periodDuration = _periodMinutes * 60; periodDuration = _periodMinutes * 60;
demurrageAmount = uint128(ppmDivider * 1000000); // Represents 38 decimal places demurrageAmount = uint128(ppmDivider * 1000000000000); // Represents 38 decimal places
//demurragePeriod = 1; //demurragePeriod = 1;
taxLevel = _taxLevelMinute; // Represents 38 decimal places taxLevel = _taxLevelMinute; // Represents 38 decimal places
bytes32 initialRedistribution = toRedistribution(0, 1000000, 0, 1); bytes32 initialRedistribution = toRedistribution(0, 1000000, 0, 1);
@ -147,7 +147,7 @@ contract DemurrageTokenSingleCap {
currentDemurragedAmount = uint128(decayBy(demurrageAmount, periodCount)); currentDemurragedAmount = uint128(decayBy(demurrageAmount, periodCount));
return (baseBalance * currentDemurragedAmount) / (ppmDivider * 1000000); return (baseBalance * currentDemurragedAmount) / (ppmDivider * 1000000000000);
} }
/// Balance unmodified by demurrage /// Balance unmodified by demurrage
@ -271,7 +271,7 @@ contract DemurrageTokenSingleCap {
} }
function getDistribution(uint256 _supply, uint256 _demurrageAmount) public view returns (uint256) { function getDistribution(uint256 _supply, uint256 _demurrageAmount) public view returns (uint256) {
return _supply * (ppmDivider - (_demurrageAmount / 1000000)); return _supply * (ppmDivider - (_demurrageAmount / 1000000000000));
} }
// Returns the amount sent to the sink address // Returns the amount sent to the sink address
@ -365,7 +365,7 @@ contract DemurrageTokenSingleCap {
uint256 truncatedTaxLevel; uint256 truncatedTaxLevel;
valueFactor = 1000000; valueFactor = 1000000;
truncatedTaxLevel = taxLevel / ppmDivider; truncatedTaxLevel = taxLevel / (ppmDivider * 1000000);
for (uint256 i = 0; i < _period; i++) { for (uint256 i = 0; i < _period; i++) {
valueFactor = valueFactor + ((valueFactor * truncatedTaxLevel) / 1000000); valueFactor = valueFactor + ((valueFactor * truncatedTaxLevel) / 1000000);
@ -380,7 +380,7 @@ contract DemurrageTokenSingleCap {
uint256 truncatedTaxLevel; uint256 truncatedTaxLevel;
valueFactor = 1000000; valueFactor = 1000000;
truncatedTaxLevel = taxLevel / ppmDivider; truncatedTaxLevel = taxLevel / (ppmDivider * 1000000);
for (uint256 i = 0; i < _period; i++) { for (uint256 i = 0; i < _period; i++) {
valueFactor = valueFactor - ((valueFactor * truncatedTaxLevel) / 1000000); valueFactor = valueFactor - ((valueFactor * truncatedTaxLevel) / 1000000);
@ -390,7 +390,7 @@ contract DemurrageTokenSingleCap {
// Inflates the given amount according to the current demurrage modifier // Inflates the given amount according to the current demurrage modifier
function toBaseAmount(uint256 _value) public view returns (uint256) { function toBaseAmount(uint256 _value) public view returns (uint256) {
return (_value * ppmDivider * 1000000) / demurrageAmount; return (_value * ppmDivider * 1000000000000) / demurrageAmount;
} }
// Implements ERC20, triggers tax and/or redistribution // Implements ERC20, triggers tax and/or redistribution