erc20-transfer-authorization

Simple approval escrow for ERC20 spending
Log | Files | Refs

commit a1ff96561cc1a5b48d2f3aff378af767a88ee7d4
parent 1ee7aab6e22f7f0eeab26e1c8e1c2676f8522982
Author: lash <dev@holbrook.no>
Date:   Sat, 10 Dec 2022 09:37:29 +0000

Implement transfer test for chainlib

Diffstat:
Mpython/erc20_transfer_authorization/transfer_authorization.py | 34++++++++++++++++++++++++----------
Mpython/tests/test_quorum.py | 16++++++++--------
Apython/tests/test_transfer.py | 87+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 119 insertions(+), 18 deletions(-)

diff --git a/python/erc20_transfer_authorization/transfer_authorization.py b/python/erc20_transfer_authorization/transfer_authorization.py @@ -64,6 +64,14 @@ class Request: return self.result & 4 > 0 + def is_transferred(self): + return self.result & 24 == 8 + + + def __str__(self): + return "{} {} {} {}".format(self.sender, self.recipient, self.value, self.result) + + class TransferAuthorization(TxFactory): @@ -212,23 +220,29 @@ class TransferAuthorization(TxFactory): return o - def check_result(self, contract_address, serial, sender_address=ZERO_ADDRESS, id_generator=None): - j = JSONRPCRequest(id_generator) - o = j.template() - o['method'] = 'eth_call' + def check_result(self, contract_address, sender_address, serial, id_generator=None, tx_format=TxFormat.JSONRPC): enc = ABIContractEncoder() enc.method('checkResult') enc.typ(ABIContractType.UINT32) enc.uintn(serial, 32) - data = add_0x(enc.get()) - tx = self.template(sender_address, contract_address) + data = enc.get() + tx = self.template(sender_address, contract_address, use_nonce=True) tx = self.set_code(tx, data) - o['params'].append(self.normalize(tx)) - o['params'].append('latest') - o = j.finalize(o) - return o + tx = self.finalize(tx, tx_format) + return tx + def execute_request(self, contract_address, sender_address, serial, id_generator=None, tx_format=TxFormat.JSONRPC): + enc = ABIContractEncoder() + enc.method('executeRequest') + enc.typ(ABIContractType.UINT32) + enc.uintn(serial, 32) + 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 + def is_writer(self, contract_address, signer_address, sender_address=ZERO_ADDRESS, id_generator=None): return self.writers(contract_address, signer_address, sender_address) diff --git a/python/tests/test_quorum.py b/python/tests/test_quorum.py @@ -7,7 +7,7 @@ import logging from chainlib.eth.nonce import RPCNonceOracle from chainlib.eth.address import is_same_address from chainlib.eth.tx import receipt -from giftable_erc20_token import GiftableToken +#from giftable_erc20_token import GiftableToken # local imports from erc20_transfer_authorization import TransferAuthorization @@ -34,13 +34,6 @@ class TestQuorum(TestBase): r = self.rpc.do(o) self.assertEqual(r['status'], 1) - c = GiftableToken(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) - (tx_hash_hex, o) = c.mint_to(self.token_address, self.accounts[0], self.accounts[1], 10000) - self.rpc.do(o) - o = receipt(tx_hash_hex) - r = self.rpc.do(o) - self.assertEqual(r['status'], 1) - def test_register(self): (tx_hash_hex, o) = self.c.set_thresholds(self.address, self.accounts[0], 2, 2) @@ -72,6 +65,12 @@ class TestQuorum(TestBase): self.assertEqual(request.yay, 1) self.assertEqual(request.nay, 0) + (tx_hash_hex, o) = self.c.check_result(self.address, self.accounts[0], 1) + self.rpc.do(o) + o = receipt(tx_hash_hex) + r = self.rpc.do(o) + self.assertEqual(r['status'], 1) + def test_simple_yay(self): (tx_hash_hex, o) = self.c.set_thresholds(self.address, self.accounts[0], 2, 2) @@ -146,6 +145,7 @@ class TestQuorum(TestBase): request = self.c.parse_request(r) self.assertFalse(request.is_accepted()) + def test_yay_nay_yay(self): (tx_hash_hex, o) = self.c.set_thresholds(self.address, self.accounts[0], 2, 2) self.rpc.do(o) diff --git a/python/tests/test_transfer.py b/python/tests/test_transfer.py @@ -0,0 +1,87 @@ +# standard imports +import os +import unittest +import logging + +# external imports +from chainlib.eth.nonce import RPCNonceOracle +from chainlib.eth.address import is_same_address +from chainlib.eth.tx import receipt +from giftable_erc20_token import GiftableToken +from eth_erc20 import ERC20 + +# local imports +from erc20_transfer_authorization import TransferAuthorization + +# testutil imports +from tests.base_erc20transferauthorization import TestBase + +logg = logging.getLogger() + +testdir = os.path.dirname(__file__) + + +class TestTransfer(TestBase): + + def setUp(self): + super(TestTransfer, self).setUp() + nonce_oracle = RPCNonceOracle(self.accounts[0], self.rpc) + self.c = TransferAuthorization(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) + + c = GiftableToken(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) + (tx_hash_hex, o) = c.mint_to(self.token_address, self.accounts[0], self.accounts[9], 10000) + self.rpc.do(o) + o = receipt(tx_hash_hex) + r = self.rpc.do(o) + self.assertEqual(r['status'], 1) + + nonce_oracle = RPCNonceOracle(self.accounts[9], self.rpc) + c = ERC20(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) + (tx_hash_hex, o) = c.approve(self.token_address, self.accounts[9], self.address, 1024) + self.rpc.do(o) + o = receipt(tx_hash_hex) + r = self.rpc.do(o) + self.assertEqual(r['status'], 1) + + + def test_transfer(self): + (tx_hash_hex, o) = self.c.create_request(self.address, self.accounts[0], self.accounts[9], self.accounts[2], self.token_address, 1024) + self.rpc.do(o) + o = receipt(tx_hash_hex) + r = self.rpc.do(o) + self.assertEqual(r['status'], 1) + + (tx_hash_hex, o) = self.c.yay(self.address, self.accounts[0], 1) + self.rpc.do(o) + o = receipt(tx_hash_hex) + r = self.rpc.do(o) + self.assertEqual(r['status'], 1) + + (tx_hash_hex, o) = self.c.check_result(self.address, self.accounts[0], 1) + r = self.rpc.do(o) + o = receipt(tx_hash_hex) + r = self.rpc.do(o) + self.assertEqual(r['status'], 1) + + (tx_hash_hex, o) = self.c.execute_request(self.address, self.accounts[0], 1) + r = self.rpc.do(o) + o = receipt(tx_hash_hex) + r = self.rpc.do(o) + self.assertEqual(r['status'], 1) + + o = self.c.requests(self.address, 1, sender_address=self.accounts[0]) + r = self.rpc.do(o) + request = self.c.parse_request(r) + logg.debug('request {}'.format(request)) + self.assertTrue(request.is_transferred()) + + nonce_oracle = RPCNonceOracle(self.accounts[0], self.rpc) + c = ERC20(self.chain_spec, nonce_oracle=nonce_oracle) + o = c.balance(self.token_address, self.accounts[9], sender_address=self.accounts[0]) + r = self.rpc.do(o) + balance = c.parse_balance(r) + self.assertEqual(balance, 10000-1024) + + +if __name__ == '__main__': + unittest.main()