erc20-transfer-authorization

Simple approval escrow for ERC20 spending
Log | Files | Refs

commit 2cf8b98b122f87c5f30f70feec117d8809bf6bba
parent 2538cb1889df4fa48adf4c9749b1ec2295ccb0ad
Author: nolash <dev@holbrook.no>
Date:   Mon, 28 Jun 2021 10:24:41 +0200

Move to chainlib-eth

Diffstat:
A.gitignore | 6++++++
Mpython/CHANGELOG | 4++++
Mpython/erc20_transfer_authorization/transfer_authorization.py | 36+++++++++++++++++++++++++++++++-----
Mpython/requirements.txt | 5+++--
Apython/run_tests.sh | 12++++++++++++
Mpython/setup.cfg | 2+-
Mpython/test_requirements.txt | 2+-
Dpython/tests/base.py | 49-------------------------------------------------
Apython/tests/base_erc20transferauthorization.py | 49+++++++++++++++++++++++++++++++++++++++++++++++++
Mpython/tests/test_app.py | 4++--
Mpython/tests/test_quorum.py | 9++++++++-
Mpython/tests/test_transfer.py | 3++-
12 files changed, 119 insertions(+), 62 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -0,0 +1,6 @@ +__pycache__ +*.pyc +*.egg-info/ +build/ +dist/ +gmon.out diff --git a/python/CHANGELOG b/python/CHANGELOG @@ -1,3 +1,7 @@ + +- 0.3.2-pending + * Move to chainlib-eth +- 0.3.1-unreleased - 0.2.0-unreleased * Implement external signer * Standardize cli arg flags diff --git a/python/erc20_transfer_authorization/transfer_authorization.py b/python/erc20_transfer_authorization/transfer_authorization.py @@ -9,7 +9,10 @@ import json import os # external imports -from chainlib.eth.tx import TxFactory +from chainlib.eth.tx import ( + TxFactory, + TxFormat, + ) from chainlib.eth.constant import ZERO_ADDRESS from chainlib.eth.contract import ( ABIContractEncoder, @@ -17,8 +20,11 @@ from chainlib.eth.contract import ( ABIContractType, abi_decode_single, ) -from chainlib.jsonrpc import jsonrpc_template -from hexathon import add_0x +from chainlib.jsonrpc import JSONRPCRequest +from hexathon import ( + add_0x, + strip_0x, + ) logg = logging.getLogger().getChild(__name__) @@ -55,6 +61,24 @@ class TransferAuthorization(TxFactory): return 2800000 + def create_request(self, contract_address, sender_address, sender, recipient, token, value, tx_format=TxFormat.JSONRPC): + enc = ABIContractEncoder() + enc.method('createRequest') + enc.typ(ABIContractType.ADDRESS) + enc.typ(ABIContractType.ADDRESS) + enc.typ(ABIContractType.ADDRESS) + enc.typ(ABIContractType.UINT256) + enc.address(sender) + enc.address(recipient) + enc.address(token) + enc.uint256(value) + 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 constructor(self, sender_address): code = TransferAuthorization.bytecode() tx = self.template(sender_address, None, use_nonce=True) @@ -62,8 +86,9 @@ class TransferAuthorization(TxFactory): return self.build(tx) - def signers(self, contract_address, signer_address, sender_address=ZERO_ADDRESS): - o = jsonrpc_template() + def signers(self, contract_address, signer_address, sender_address=ZERO_ADDRESS, id_generator=None): + j = JSONRPCRequest(id_generator) + o = j.template() o['method'] = 'eth_call' enc = ABIContractEncoder() enc.method('signers') @@ -74,6 +99,7 @@ class TransferAuthorization(TxFactory): tx = self.set_code(tx, data) o['params'].append(self.normalize(tx)) o['params'].append('latest') + o = j.finalize(o) return o diff --git a/python/requirements.txt b/python/requirements.txt @@ -1,3 +1,4 @@ confini~=0.3.6rc3 -crypto-dev-signer~=0.4.14b3 -chainlib~=0.0.3a1 +crypto-dev-signer~=0.4.14b6 +chainlib~=0.0.5a1 +potaahto~=0.0.1a2 diff --git a/python/run_tests.sh b/python/run_tests.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +set -e +set -x +for f in `ls tests/*.py`; do + python $f + if [ $? -gt 0 ]; then + exit 1 + fi +done +set +x +set +e diff --git a/python/setup.cfg b/python/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = erc20-transfer-authorization -version = 0.3.1a6 +version = 0.3.2a1 description = Simple approval escrow for ERC20 spend approval author = Louis Holbrook author_email = dev@holbrook.no diff --git a/python/test_requirements.txt b/python/test_requirements.txt @@ -1,3 +1,3 @@ eth-tester==0.5.0b3 py-evm==0.3.0a20 -#giftable-erc20-token==0.0.8a9 +eth-erc20~=0.0.10a1 diff --git a/python/tests/base.py b/python/tests/base.py @@ -1,49 +0,0 @@ -# standard imports -import os -import unittest -import json -import logging - -# external imports -from chainlib.eth.unittest.ethtester import EthTesterCase -from chainlib.eth.nonce import RPCNonceOracle -from chainlib.eth.tx import receipt -from giftable_erc20_token import GiftableToken - -# local imports -from erc20_transfer_authorization import TransferAuthorization - -logging.basicConfig(level=logging.DEBUG) -logg = logging.getLogger() - -logging.getLogger('web3').setLevel(logging.WARNING) -logging.getLogger('eth.vm').setLevel(logging.WARNING) - -testdir = os.path.dirname(__file__) - - -class TestBase(EthTesterCase): - - def setUp(self): - super(TestBase, self).setUp() - nonce_oracle = RPCNonceOracle(self.accounts[0], self.rpc) - c = TransferAuthorization(signer=self.signer, nonce_oracle=nonce_oracle, chain_id=self.chain_spec.chain_id()) - (tx_hash_hex, o) = c.constructor(self.accounts[0]) - - self.rpc.do(o) - - o = receipt(tx_hash_hex) - r = self.rpc.do(o) - self.assertEqual(r['status'], 1) - - self.address = r['contract_address'] - - c = GiftableToken(signer=self.signer, nonce_oracle=nonce_oracle, chain_id=self.chain_spec.chain_id()) - (tx_hash_hex, o) = c.constructor(self.accounts[0], 'FooToken', 'FOO', 6) - self.rpc.do(o) - - o = receipt(tx_hash_hex) - r = self.rpc.do(o) - self.assertEqual(r['status'], 1) - - self.token_address = r['contract_address'] diff --git a/python/tests/base_erc20transferauthorization.py b/python/tests/base_erc20transferauthorization.py @@ -0,0 +1,49 @@ +# standard imports +import os +import unittest +import json +import logging + +# external imports +from chainlib.eth.unittest.ethtester import EthTesterCase +from chainlib.eth.nonce import RPCNonceOracle +from chainlib.eth.tx import receipt +from giftable_erc20_token import GiftableToken + +# local imports +from erc20_transfer_authorization import TransferAuthorization + +logging.basicConfig(level=logging.DEBUG) +logg = logging.getLogger() + +logging.getLogger('web3').setLevel(logging.WARNING) +logging.getLogger('eth.vm').setLevel(logging.WARNING) + +testdir = os.path.dirname(__file__) + + +class TestBase(EthTesterCase): + + def setUp(self): + super(TestBase, self).setUp() + nonce_oracle = RPCNonceOracle(self.accounts[0], self.rpc) + c = TransferAuthorization(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) + (tx_hash_hex, o) = c.constructor(self.accounts[0]) + + self.rpc.do(o) + + o = receipt(tx_hash_hex) + r = self.rpc.do(o) + self.assertEqual(r['status'], 1) + + self.address = r['contract_address'] + + c = GiftableToken(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) + (tx_hash_hex, o) = c.constructor(self.accounts[0], 'FooToken', 'FOO', 6) + self.rpc.do(o) + + o = receipt(tx_hash_hex) + r = self.rpc.do(o) + self.assertEqual(r['status'], 1) + + self.token_address = r['contract_address'] diff --git a/python/tests/test_app.py b/python/tests/test_app.py @@ -10,7 +10,7 @@ from chainlib.eth.nonce import RPCNonceOracle from erc20_transfer_authorization import TransferAuthorization # testutil imports -from tests.base import TestBase +from tests.base_erc20transferauthorization import TestBase logg = logging.getLogger() @@ -22,7 +22,7 @@ class ERC20TransferAuthorizationBasicTest(TestBase): def test_basic(self): nonce_oracle = RPCNonceOracle(self.accounts[0], self.rpc) - c = TransferAuthorization(chain_id=self.chain_spec.chain_id()) + c = TransferAuthorization(self.chain_spec) o = c.signers(self.address, self.accounts[0], sender_address=self.accounts[0]) r = self.rpc.do(o) diff --git a/python/tests/test_quorum.py b/python/tests/test_quorum.py @@ -3,7 +3,7 @@ import logging import unittest # testutil imports -from tests.base import TestBase +from tests.base_erc20transferauthorization import TestBase logg = logging.getLogger() @@ -14,6 +14,7 @@ approved_log_signature = '36ea04725f8aa40ee603224671681b753f9cba3cb5f67c5a0e24a3 class ERC20TransferAuthorizationQuorumTest(TestBase): + @unittest.skip('must be ported to chainlib') def test_vote_access(self): w = self.w3.eth.contract(abi=self.abi_wallet, address=self.address_wallet) t = self.w3.eth.contract(abi=self.abi_token, address=self.address_token) @@ -59,6 +60,7 @@ class ERC20TransferAuthorizationQuorumTest(TestBase): tx_hashh = w.functions.yay(serial).transact({'from': self.w3.eth.accounts[5]}) + @unittest.skip('must be ported to chainlib') def test_minimal_quorum(self): w = self.w3.eth.contract(abi=self.abi_wallet, address=self.address_wallet) t = self.w3.eth.contract(abi=self.abi_token, address=self.address_token) @@ -102,6 +104,7 @@ class ERC20TransferAuthorizationQuorumTest(TestBase): self.assertEqual(t.functions.balanceOf(self.w3.eth.accounts[3]).call(), 10) + @unittest.skip('must be ported to chainlib') def test_simple_quorum(self): w = self.w3.eth.contract(abi=self.abi_wallet, address=self.address_wallet) t = self.w3.eth.contract(abi=self.abi_token, address=self.address_token) @@ -148,6 +151,7 @@ class ERC20TransferAuthorizationQuorumTest(TestBase): w.functions.nay(serial).transact({'from': self.w3.eth.accounts[6]}) + @unittest.skip('must be ported to chainlib') def test_minimal_rejection(self): w = self.w3.eth.contract(abi=self.abi_wallet, address=self.address_wallet) t = self.w3.eth.contract(abi=self.abi_token, address=self.address_token) @@ -174,6 +178,7 @@ class ERC20TransferAuthorizationQuorumTest(TestBase): w.functions.executeRequest(serial).transact({'from': self.w3.eth.accounts[0]}) + @unittest.skip('must be ported to chainlib') def test_simple_rejection(self): w = self.w3.eth.contract(abi=self.abi_wallet, address=self.address_wallet) t = self.w3.eth.contract(abi=self.abi_token, address=self.address_token) @@ -218,6 +223,7 @@ class ERC20TransferAuthorizationQuorumTest(TestBase): w.functions.nay(serial).transact({'from': self.w3.eth.accounts[6]}) + @unittest.skip('must be ported to chainlib') def test_veto(self): w = self.w3.eth.contract(abi=self.abi_wallet, address=self.address_wallet) t = self.w3.eth.contract(abi=self.abi_token, address=self.address_token) @@ -259,6 +265,7 @@ class ERC20TransferAuthorizationQuorumTest(TestBase): w.functions.nay(serial).transact({'from': self.w3.eth.accounts[6]}) + @unittest.skip('must be ported to chainlib') def test_inflight_change(self): w = self.w3.eth.contract(abi=self.abi_wallet, address=self.address_wallet) t = self.w3.eth.contract(abi=self.abi_token, address=self.address_token) diff --git a/python/tests/test_transfer.py b/python/tests/test_transfer.py @@ -3,13 +3,14 @@ import logging import unittest # testutil imports -from tests.base import TestBase +from tests.base_erc20transferauthorization import TestBase logg = logging.getLogger() class ERC20TransferAuthorizationTransferTest(TestBase): + @unittest.skip('must be ported to chainlib') def test_transfer(self): w = self.w3.eth.contract(abi=self.abi_wallet, address=self.address_wallet) t = self.w3.eth.contract(abi=self.abi_token, address=self.address_token)