erc20-demurrage-token

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

demurrage.py (2738B)


      1 # standard imports
      2 import logging
      3 import datetime
      4 import math
      5 
      6 # eternal imports
      7 from chainlib.eth.constant import ZERO_ADDRESS
      8 
      9 # local imports
     10 from .token import DemurrageToken
     11 
     12 logg = logging.getLogger(__name__)
     13 
     14 
     15 class DemurrageCalculator:
     16 
     17     def __init__(self, interest_f_minute):
     18 
     19         self.r_min = interest_f_minute
     20         self.r_hour = 1 - ((1 -self.r_min) ** 60)
     21         self.r_day = 1 - ((1 -self.r_hour) ** 24)
     22         #self.r_week = interest_f_day ** 7
     23         logg.info('demurrage calculator set with min {:.32f} hour {:.32f} day {:.32f}'.format(self.r_min, self.r_hour, self.r_day))
     24 
     25 
     26     def amount_since(self, amount, timestamp):
     27         delta = datetime.datetime.utcnow() - datetime.datetime.fromtimestamp(timestamp)
     28         adjusted_amount = amount * ((1 - self.r_day) ** (delta.days))
     29         logg.debug('adjusted for {} days {} -> {}'.format(delta.days, amount, adjusted_amount))
     30 
     31         remainder = delta.seconds
     32         remainder_hours = math.floor(remainder / (60 * 60))
     33         adjusted_delta = adjusted_amount * ((1 - self.r_hour) ** remainder_hours)
     34         adjusted_amount -= (adjusted_amount - adjusted_delta)
     35         logg.debug('adjusted for {} hours {} -> {} delta {}'.format(remainder_hours, amount, adjusted_amount, adjusted_delta))
     36 
     37         remainder -= (remainder_hours * (60 * 60))
     38         remainder_minutes = math.floor(remainder / 60)
     39         adjusted_delta = adjusted_amount * ((1 - self.r_min) ** remainder_minutes)
     40         adjusted_amount -= (adjusted_amount - adjusted_delta)
     41         logg.debug('adjusted for {} minutes {} -> {} delta {}'.format(remainder_minutes, amount, adjusted_amount, adjusted_delta))
     42 
     43         return adjusted_amount
     44 
     45     
     46     def amount_since_slow(self, amount, timestamp):
     47         delta = datetime.datetime.utcnow() - datetime.datetime.fromtimestamp(timestamp)
     48         remainder_minutes = math.floor(delta.total_seconds() / 60)
     49         adjusted_amount = amount * ((1 - self.r_min) ** remainder_minutes)
     50         logg.debug('adjusted for {} minutes {} -> {} delta {}'.format(remainder_minutes, amount, adjusted_amount, amount - adjusted_amount))
     51 
     52         return adjusted_amount
     53 
     54 
     55     @staticmethod
     56     def from_contract(rpc, chain_spec, contract_address, sender_address=ZERO_ADDRESS):
     57         c = DemurrageToken(chain_spec)
     58         o = c.tax_level(contract_address, sender_address=sender_address)
     59         r = rpc.do(o)
     60         taxlevel_i = c.parse_tax_level(r)
     61 
     62         o = c.resolution_factor(contract_address, sender_address=sender_address)
     63         r = rpc.do(o)
     64         divider = c.parse_resolution_factor(r)
     65         logg.debug('taxlevel {} f {}'.format(taxlevel_i, divider))
     66         taxlevel_f = taxlevel_i / divider
     67         return DemurrageCalculator(taxlevel_f)