From 00bb87e3ec9ab2af34e04a8f35a21c2b45d5f8b7 Mon Sep 17 00:00:00 2001 From: nolash Date: Fri, 2 Jul 2021 15:29:56 +0200 Subject: [PATCH] Add python demurrage calculator --- python/erc20_demurrage_token/demurrage.py | 38 +++++++++++++++++++++++ python/setup.cfg | 2 +- python/test.sh | 33 -------------------- python/tests/test_demurrage_ext.py | 23 ++++++++++++++ 4 files changed, 62 insertions(+), 34 deletions(-) create mode 100644 python/erc20_demurrage_token/demurrage.py delete mode 100644 python/test.sh create mode 100644 python/tests/test_demurrage_ext.py diff --git a/python/erc20_demurrage_token/demurrage.py b/python/erc20_demurrage_token/demurrage.py new file mode 100644 index 0000000..e97e769 --- /dev/null +++ b/python/erc20_demurrage_token/demurrage.py @@ -0,0 +1,38 @@ +# +import logging +import datetime +import math + +logging.basicConfig(level=logging.DEBUG) +logg = logging.getLogger() + + +class DemurrageCalculator: + + def __init__(self, interest_f_minute): + + self.r_min = interest_f_minute + self.r_hour = 1 - ((1 -self.r_min) ** 60) + self.r_day = 1 - ((1 -self.r_hour) ** 24) + #self.r_week = interest_f_day ** 7 + logg.info('demurrage calculator set with min {:.32f} hour {:.32f} day {:.32f}'.format(self.r_min, self.r_hour, self.r_day)) + + + def amount_since(self, amount, timestamp): + delta = datetime.datetime.utcnow() - datetime.datetime.fromtimestamp(timestamp) + adjusted_amount = amount * ((1 - self.r_day) ** (delta.days)) + logg.debug('adjusted for {} days {} -> {}'.format(delta.days, amount, adjusted_amount)) + + remainder = delta.seconds + remainder_hours = math.floor(remainder / (60 * 60)) + adjusted_delta = adjusted_amount * ((1 - self.r_hour) ** remainder_hours) + adjusted_amount -= (adjusted_amount - adjusted_delta) + logg.debug('adjusted for {} hours {} -> {} delta {}'.format(remainder_hours, amount, adjusted_amount, adjusted_delta)) + + remainder -= (remainder_hours * (60 * 60)) + remainder_minutes = math.floor(remainder / 60) + adjusted_delta = adjusted_amount * ((1 - self.r_min) ** remainder_minutes) + adjusted_amount -= (adjusted_amount - adjusted_delta) + logg.debug('adjusted for {} hours {} -> {} delta {}'.format(remainder_minutes, amount, adjusted_amount, adjusted_delta)) + + return adjusted_amount diff --git a/python/setup.cfg b/python/setup.cfg index d8edfae..7185900 100644 --- a/python/setup.cfg +++ b/python/setup.cfg @@ -4,7 +4,7 @@ version = 0.0.2a1 description = ERC20 token with redistributed continual demurrage author = Louis Holbrook author_email = dev@holbrook.no -url = https://gitlab.com/grassrootseconomics/sarafu-token +url = https://gitlab.com/ccicnet/erc20-demurrage-token keywords = ethereum blockchain diff --git a/python/test.sh b/python/test.sh deleted file mode 100644 index 9bea348..0000000 --- a/python/test.sh +++ /dev/null @@ -1,33 +0,0 @@ -#!/bin/bash - -set -e - -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_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) -for m in ${modes[@]}; do - ERC20_DEMURRAGE_TOKEN_TEST_MODE=$m python tests/test_cap.py -done - -#modes=(MultiCap MultiNocap) -#for m in ${modes[@]}; do -# ERC20_DEMURRAGE_TOKEN_TEST_MODE=$m python tests/test_remainder.py -# ERC20_DEMURRAGE_TOKEN_TEST_MODE=$m python tests/test_redistribution.py -#done - -set +e diff --git a/python/tests/test_demurrage_ext.py b/python/tests/test_demurrage_ext.py new file mode 100644 index 0000000..2090a6f --- /dev/null +++ b/python/tests/test_demurrage_ext.py @@ -0,0 +1,23 @@ +# standard imports +import datetime +import unittest + +# local imports +from erc20_demurrage_token.demurrage import DemurrageCalculator + +# test imports +from tests.base import TestDemurrage + + +class TestEmulate(TestDemurrage): + + def test_amount_since(self): + + d = datetime.datetime.utcnow() - datetime.timedelta(seconds=29, hours=5, minutes=3, days=4) + c = DemurrageCalculator(0.00000050105908373373) + a = c.amount_since(100, d.timestamp()) + self.assert_within_lower(a, 99.69667, 0.1) + + +if __name__ == '__main__': + unittest.main()