commit 09b825808fe97b2f7da60641cbd55a86d406d401
parent 2717e29d91dd2b5f4a7efd14e28a44a11f14c66d
Author: lash <dev@holbrook.no>
Date: Fri, 10 Feb 2023 13:45:29 +0000
Freeze accounts balances at expiry
Diffstat:
3 files changed, 132 insertions(+), 0 deletions(-)
diff --git a/python/erc20_demurrage_token/expiry.py b/python/erc20_demurrage_token/expiry.py
@@ -0,0 +1,22 @@
+# external imports
+from chainlib.eth.tx import (
+ TxFactory,
+ TxFormat,
+ )
+from chainlib.eth.contract import (
+ ABIContractEncoder,
+ ABIContractType,
+ )
+
+class ExpiryContract(TxFactory):
+
+ def set_expires(self, contract_address, sender_address, expire_timestamp, tx_format=TxFormat.JSONRPC):
+ enc = ABIContractEncoder()
+ enc.method('setExpires')
+ enc.typ(ABIContractType.UINT256)
+ enc.uint256(expire_timestamp)
+ data = enc.get()
+ tx = self.template(sender_address, contract_address, use_nonce=True)
+ tx = self.set_code(tx, data)
+ tx = self.finalize(tx, tx_format)
+ return tx
diff --git a/python/erc20_demurrage_token/seal.py b/python/erc20_demurrage_token/seal.py
@@ -0,0 +1,21 @@
+# external imports
+from chainlib.eth.tx import (
+ TxFactory,
+ TxFormat,
+ )
+from chainlib.eth.contract import (
+ ABIContractEncoder,
+ )
+
+class SealedContract(TxFactory):
+
+ def set_state(self, contract_address, sender_address, seal, tx_format=TxFormat.JSONRPC):
+ enc = ABIContractEncoder()
+ enc.method('seal')
+ enc.typ(ABIContractType.UINT256)
+ enc.uint256(seal)
+ data = enc.get()
+ tx = self.template(sender_address, contract_address, use_nonce=True)
+ tx = self.set_code(tx, data)
+ tx = self.finalize(tx, tx_format)
+ return tx
diff --git a/python/tests/test_expiry.py b/python/tests/test_expiry.py
@@ -0,0 +1,89 @@
+# standard imports
+import os
+import unittest
+import json
+import logging
+import datetime
+
+# external imports
+from chainlib.eth.constant import ZERO_ADDRESS
+from chainlib.eth.nonce import RPCNonceOracle
+from chainlib.eth.tx import receipt
+from chainlib.eth.block import (
+ block_latest,
+ block_by_number,
+ )
+
+# local imports
+from erc20_demurrage_token import DemurrageToken
+
+# test imports
+from erc20_demurrage_token.unittest import TestDemurrageDefault
+
+logging.basicConfig(level=logging.DEBUG)
+logg = logging.getLogger()
+
+testdir = os.path.dirname(__file__)
+
+
+class TestExpire(TestDemurrageDefault):
+
+ def test_expires(self):
+ mint_amount = self.default_supply
+ nonce_oracle = RPCNonceOracle(self.accounts[0], self.rpc)
+ c = DemurrageToken(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle)
+
+ for i in range(3):
+ (tx_hash, o) = c.mint_to(self.address, self.accounts[0], self.accounts[i+1], mint_amount)
+ r = self.rpc.do(o)
+
+ targetish_time = self.start_time + (self.period_seconds * 2)
+ (tx_hash, o) = c.set_expires(self.address, self.accounts[0], targetish_time)
+ r = self.rpc.do(o)
+ o = receipt(tx_hash)
+ r = self.rpc.do(o)
+ self.assertEqual(r['status'], 1)
+
+ self.backend.time_travel(targetish_time + 60)
+ o = block_latest()
+ r = self.rpc.do(o)
+ o = block_by_number(r)
+ r = self.rpc.do(o)
+ self.assertGreaterEqual(r['timestamp'], targetish_time)
+
+ nonce_oracle = RPCNonceOracle(self.sink_address, self.rpc)
+ c = DemurrageToken(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle)
+ (tx_hash, o) = c.transfer(self.address, self.sink_address, self.accounts[2], 1)
+ 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(r)
+ self.assert_within(balance, 0.9604 * mint_amount, 1)
+
+ o = c.total_supply(self.address, sender_address=self.accounts[0])
+ r = self.rpc.do(o)
+ supply = c.parse_balance(r)
+
+ (tx_hash, o) = c.change_period(self.address, self.sink_address)
+ 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.sink_address, sender_address=self.accounts[0])
+ r = self.rpc.do(o)
+ balance = c.parse_balance(r)
+
+ o = c.decay_by(self.address, supply, int((targetish_time - self.start_time) / 60), sender_address=self.sink_address)
+ r = self.rpc.do(o)
+ target_balance = c.parse_balance(r)
+
+ self.assert_within_lower(balance, supply - target_balance, 0.0001)
+
+
+if __name__ == '__main__':
+ unittest.main()