mirror of
git://holbrook.no/erc20-demurrage-token
synced 2024-11-25 17:26:45 +01:00
WIP avoid fractional truncation
This commit is contained in:
parent
dd878aa5cd
commit
5f69a1d7a1
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -65,7 +65,17 @@ class DemurrageTokenSimulation:
|
|||||||
r = self.rpc.do(o)
|
r = self.rpc.do(o)
|
||||||
if r['status'] != 1:
|
if r['status'] != 1:
|
||||||
raise RuntimeError('failed gas transfer to account #{}: {} from {}'.format(i, address, self.accounts[idx]))
|
raise RuntimeError('failed gas transfer to account #{}: {} from {}'.format(i, address, self.accounts[idx]))
|
||||||
logg.debug('added actor account #{}: {}'.format(i, address))
|
logg.info('added actor account #{}: {} block {}'.format(i, address, r['block_number']))
|
||||||
|
|
||||||
|
c = DemurrageToken(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle)
|
||||||
|
(tx_hash, o) = c.constructor(self.accounts[0], settings, redistribute=redistribute, cap=cap)
|
||||||
|
self.rpc.do(o)
|
||||||
|
o = receipt(tx_hash)
|
||||||
|
r = self.rpc.do(o)
|
||||||
|
if (r['status'] != 1):
|
||||||
|
raise RuntimeError('contract deployment failed')
|
||||||
|
self.address = r['contract_address']
|
||||||
|
logg.info('deployed contract to {} block {}'.format(self.address, r['block_number']))
|
||||||
|
|
||||||
o = block_latest()
|
o = block_latest()
|
||||||
r = self.rpc.do(o)
|
r = self.rpc.do(o)
|
||||||
@ -76,25 +86,14 @@ class DemurrageTokenSimulation:
|
|||||||
r = self.rpc.do(o)
|
r = self.rpc.do(o)
|
||||||
self.last_timestamp = r['timestamp']
|
self.last_timestamp = r['timestamp']
|
||||||
self.start_timestamp = self.last_timestamp
|
self.start_timestamp = self.last_timestamp
|
||||||
|
|
||||||
nonce_oracle = RPCNonceOracle(self.accounts[0], conn=self.rpc)
|
nonce_oracle = RPCNonceOracle(self.accounts[0], conn=self.rpc)
|
||||||
|
|
||||||
c = DemurrageToken(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle)
|
|
||||||
(tx_hash, o) = c.constructor(self.accounts[0], settings, redistribute=redistribute, cap=cap)
|
|
||||||
self.rpc.do(o)
|
|
||||||
o = receipt(tx_hash)
|
|
||||||
r = self.rpc.do(o)
|
|
||||||
if (r['status'] != 1):
|
|
||||||
raise RuntimeError('contract deployment failed')
|
|
||||||
self.address = r['contract_address']
|
|
||||||
|
|
||||||
o = c.decimals(self.address, sender_address=self.accounts[0])
|
o = c.decimals(self.address, sender_address=self.accounts[0])
|
||||||
r = self.rpc.do(o)
|
r = self.rpc.do(o)
|
||||||
self.decimals = c.parse_decimals(r)
|
self.decimals = c.parse_decimals(r)
|
||||||
|
|
||||||
self.period_seconds = settings.period_minutes * 60
|
self.period_seconds = settings.period_minutes * 60
|
||||||
|
|
||||||
self.last_block += 1
|
|
||||||
self.last_timestamp += 1
|
|
||||||
self.period = 1
|
self.period = 1
|
||||||
self.period_txs = []
|
self.period_txs = []
|
||||||
self.period_tx_limit = self.period_seconds - 1
|
self.period_tx_limit = self.period_seconds - 1
|
||||||
@ -146,12 +145,15 @@ class DemurrageTokenSimulation:
|
|||||||
|
|
||||||
|
|
||||||
def get_period(self):
|
def get_period(self):
|
||||||
return self.period
|
o = self.caller_contract.actual_period(self.address, sender_address=self.caller_address)
|
||||||
|
r = self.rpc.do(o)
|
||||||
|
return self.caller_contract.parse_actual_period(r)
|
||||||
|
|
||||||
|
|
||||||
def get_demurrage(self):
|
def get_demurrage(self):
|
||||||
o = self.caller_contract.demurrage_amount(self.address, sender_address=self.caller_address)
|
o = self.caller_contract.demurrage_amount(self.address, sender_address=self.caller_address)
|
||||||
r = self.rpc.do(o)
|
r = self.rpc.do(o)
|
||||||
|
logg.info('demrrage amount {}'.format(r))
|
||||||
return float(self.caller_contract.parse_demurrage_amount(r) / (10 ** 38))
|
return float(self.caller_contract.parse_demurrage_amount(r) / (10 ** 38))
|
||||||
|
|
||||||
|
|
||||||
@ -218,21 +220,54 @@ class DemurrageTokenSimulation:
|
|||||||
|
|
||||||
def next(self):
|
def next(self):
|
||||||
target_timestamp = self.start_timestamp + (self.period * self.period_seconds)
|
target_timestamp = self.start_timestamp + (self.period * self.period_seconds)
|
||||||
logg.debug('warping to {}, {} from start'.format(target_timestamp, target_timestamp - self.start_timestamp))
|
logg.info('warping to {}, {} from start {}'.format(target_timestamp, target_timestamp - self.start_timestamp, self.start_timestamp))
|
||||||
self.last_timestamp = target_timestamp
|
self.last_timestamp = target_timestamp
|
||||||
|
|
||||||
self.eth_helper.time_travel(self.last_timestamp)
|
o = block_latest()
|
||||||
|
r = self.rpc.do(o)
|
||||||
|
self.last_block = r
|
||||||
|
o = block_by_number(r)
|
||||||
|
r = self.rpc.do(o)
|
||||||
|
cursor_timestamp = r['timestamp'] + 1
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
i = 0
|
||||||
|
while cursor_timestamp < target_timestamp:
|
||||||
|
logg.info('mining block on {}'.format(cursor_timestamp))
|
||||||
|
(tx_hash, o) = c.apply_demurrage(self.address, self.accounts[2])
|
||||||
|
self.rpc.do(o)
|
||||||
|
self.eth_helper.time_travel(cursor_timestamp + 60)
|
||||||
|
self.__next_block()
|
||||||
|
o = receipt(tx_hash)
|
||||||
|
r = self.rpc.do(o)
|
||||||
|
if r['status'] == 0:
|
||||||
|
raise RuntimeError('demurrage fast-forward failed on step {} timestamp {} block timestamp {} target {}'.format(i, cursor_timestamp, target_timestamp))
|
||||||
|
cursor_timestamp += 60*60 # 1 hour
|
||||||
|
o = block_by_number(r['block_number'])
|
||||||
|
b = self.rpc.do(o)
|
||||||
|
logg.info('block mined on timestamp {} (delta {}) block number {}'.format(b['timestamp'], b['timestamp'] - self.start_timestamp, b['number']))
|
||||||
|
i += 1
|
||||||
|
|
||||||
|
|
||||||
|
(tx_hash, o) = c.apply_demurrage(self.address, self.accounts[2])
|
||||||
|
self.rpc.do(o)
|
||||||
|
|
||||||
|
nonce_oracle = RPCNonceOracle(self.accounts[3], 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[3])
|
||||||
|
self.rpc.do(o)
|
||||||
|
self.eth_helper.time_travel(target_timestamp + 1)
|
||||||
self.__next_block()
|
self.__next_block()
|
||||||
|
|
||||||
|
o = block_latest()
|
||||||
|
r = self.rpc.do(o)
|
||||||
o = block_by_number(self.last_block)
|
o = block_by_number(self.last_block)
|
||||||
r = self.rpc.do(o)
|
r = self.rpc.do(o)
|
||||||
self.last_block = r['number']
|
self.last_block = r['number']
|
||||||
block_base = self.last_block
|
block_base = self.last_block
|
||||||
|
logg.info('block before demurrage execution {} {}'.format(r['timestamp'], r['number']))
|
||||||
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)
|
|
||||||
|
|
||||||
if self.redistribute:
|
if self.redistribute:
|
||||||
for actor in self.actors:
|
for actor in self.actors:
|
||||||
|
@ -5,10 +5,10 @@ import logging
|
|||||||
from erc20_demurrage_token import DemurrageTokenSettings
|
from erc20_demurrage_token import DemurrageTokenSettings
|
||||||
from erc20_demurrage_token.sim import DemurrageTokenSimulation
|
from erc20_demurrage_token.sim import DemurrageTokenSimulation
|
||||||
|
|
||||||
logging.basicConfig(level=logging.WARNING)
|
logging.basicConfig(level=logging.INFO)
|
||||||
logg = logging.getLogger()
|
logg = logging.getLogger()
|
||||||
|
|
||||||
decay_per_minute = 0.000050105908373373 # equals approx 2% per month
|
decay_per_minute = 0.00000050105908373373 # equals approx 2% per month
|
||||||
|
|
||||||
# parameters for simulation object
|
# parameters for simulation object
|
||||||
settings = DemurrageTokenSettings()
|
settings = DemurrageTokenSettings()
|
||||||
@ -16,7 +16,8 @@ settings.name = 'Simulated Demurrage Token'
|
|||||||
settings.symbol = 'SIM'
|
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
|
||||||
chain = 'evm:foochain:42'
|
chain = 'evm:foochain:42'
|
||||||
cap = (10 ** 6) * (10 ** 12)
|
cap = (10 ** 6) * (10 ** 12)
|
||||||
|
|
||||||
@ -49,8 +50,8 @@ print('sink balance: demurraged {:>9d} base {:>9d}'.format(sim.balance(sim.sink
|
|||||||
|
|
||||||
# get times
|
# get times
|
||||||
minutes = sim.get_minutes()
|
minutes = sim.get_minutes()
|
||||||
start = sim.get_now()
|
timestamp = sim.get_now()
|
||||||
timestamp = sim.get_start()
|
start = sim.get_start()
|
||||||
period = sim.get_period()
|
period = sim.get_period()
|
||||||
print('start {} now {} period {} minutes passed {}'.format(start, timestamp, period, minutes))
|
print('start {} now {} period {} minutes passed {}'.format(start, timestamp, period, minutes))
|
||||||
|
|
||||||
|
@ -138,7 +138,7 @@ class TestRedistribution(TestDemurrageUnit):
|
|||||||
o = c.demurrage_amount(self.address, sender_address=self.accounts[0])
|
o = c.demurrage_amount(self.address, sender_address=self.accounts[0])
|
||||||
r = self.rpc.do(o)
|
r = self.rpc.do(o)
|
||||||
demurrage = c.parse_demurrage_amount(r)
|
demurrage = c.parse_demurrage_amount(r)
|
||||||
logg.debug('\ndemurrage {}\nsupply {}'.format(demurrage, supply))
|
logg.debug('\nrediistribution {}\ndemurrage {}\nsupply {}'.format(redistribution, demurrage, supply))
|
||||||
|
|
||||||
expected_balance = int(supply * (self.tax_level / 1000000))
|
expected_balance = int(supply * (self.tax_level / 1000000))
|
||||||
expected_balance_tolerance = 1
|
expected_balance_tolerance = 1
|
||||||
|
@ -270,15 +270,18 @@ contract DemurrageTokenSingleCap {
|
|||||||
return lastRedistribution;
|
return lastRedistribution;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getDistribution(uint256 _supply, uint256 _demurrageAmount) public view returns (uint256) {
|
||||||
|
return _supply * (ppmDivider - (_demurrageAmount / 1000000));
|
||||||
|
}
|
||||||
|
|
||||||
// Returns the amount sent to the sink address
|
// Returns the amount sent to the sink address
|
||||||
function applyDefaultRedistribution(bytes32 _redistribution) private returns (uint256) {
|
function applyDefaultRedistribution(bytes32 _redistribution) private returns (uint256) {
|
||||||
uint256 redistributionSupply;
|
uint256 redistributionSupply;
|
||||||
uint256 unit;
|
uint256 unit;
|
||||||
|
|
||||||
redistributionSupply = toRedistributionSupply(_redistribution);
|
redistributionSupply = toRedistributionSupply(_redistribution);
|
||||||
unit = redistributionSupply * (ppmDivider - (demurrageAmount / 1000000));
|
unit = getDistribution(redistributionSupply, demurrageAmount);
|
||||||
|
increaseBaseBalance(sinkAddress, toBaseAmount(unit / ppmDivider));
|
||||||
increaseBaseBalance(sinkAddress, unit / ppmDivider);
|
|
||||||
return unit;
|
return unit;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -292,7 +295,6 @@ contract DemurrageTokenSingleCap {
|
|||||||
uint128 epochPeriodCount;
|
uint128 epochPeriodCount;
|
||||||
uint256 periodCount;
|
uint256 periodCount;
|
||||||
uint256 lastDemurrageAmount;
|
uint256 lastDemurrageAmount;
|
||||||
uint256 newDemurrageAmount;
|
|
||||||
|
|
||||||
//epochPeriodCount = actualPeriod();
|
//epochPeriodCount = actualPeriod();
|
||||||
//periodCount = epochPeriodCount - demurragePeriod;
|
//periodCount = epochPeriodCount - demurragePeriod;
|
||||||
@ -304,8 +306,8 @@ contract DemurrageTokenSingleCap {
|
|||||||
lastDemurrageAmount = demurrageAmount;
|
lastDemurrageAmount = demurrageAmount;
|
||||||
demurrageAmount = uint128(decayBy(lastDemurrageAmount, periodCount));
|
demurrageAmount = uint128(decayBy(lastDemurrageAmount, periodCount));
|
||||||
//demurragePeriod = epochPeriodCount;
|
//demurragePeriod = epochPeriodCount;
|
||||||
demurrageTimestamp = periodStart + (periodCount * 60);
|
demurrageTimestamp = demurrageTimestamp + (periodCount * 60);
|
||||||
emit Decayed(block.timestamp, periodCount, lastDemurrageAmount, demurrageAmount);
|
emit Decayed(demurrageTimestamp, periodCount, lastDemurrageAmount, demurrageAmount);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user