erc20-transfer-authorization

Simple approval escrow for ERC20 spending
Log | Files | Refs

commit dccb16a7369805f53498cb2bc441d13141072118
parent 503317d1bff36dff67a8b8b630ccbace5281a629
Author: nolash <dev@holbrook.no>
Date:   Tue, 23 Mar 2021 12:24:31 +0100

Implement chainlib for constructor, rehabilitate basic test

Diffstat:
Mpython/erc20_transfer_authorization/__init__.py | 2+-
Dpython/erc20_transfer_authorization/approval.py | 71-----------------------------------------------------------------------
Apython/erc20_transfer_authorization/transfer_authorization.py | 134+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mpython/requirements.txt | 4++--
Mpython/setup.cfg | 6+++---
Mpython/test_requirements.txt | 3++-
Mpython/tests/base.py | 74++++++++++++++++++++++++++------------------------------------------------
Mpython/tests/test_app.py | 276+++++++++++++++++++++++++++++++++++++++++--------------------------------------
8 files changed, 313 insertions(+), 257 deletions(-)

diff --git a/python/erc20_transfer_authorization/__init__.py b/python/erc20_transfer_authorization/__init__.py @@ -1 +1 @@ -from .approval import TransferApproval +from .transfer_authorization import TransferAuthorization diff --git a/python/erc20_transfer_authorization/approval.py b/python/erc20_transfer_authorization/approval.py @@ -1,71 +0,0 @@ -# Author: Louis Holbrook <dev@holbrook.no> 0826EDA1702D1E87C6E2875121D2E7BB88C2A746 -# SPDX-License-Identifier: GPL-3.0-or-later -# File-version: 1 -# Description: Python interface to abi and bin files for faucet contracts - -# standard imports -import logging -import json -import os - -logg = logging.getLogger(__name__) - -moddir = os.path.dirname(__file__) -datadir = os.path.join(moddir, 'data') - - -class TransferApproval: - - __abi = None - __bytecode = None - __address = None - - def __init__(self, w3, address, signer_address=None): - abi = TransferApproval.abi() - TransferApproval.bytecode() - self.__address = address - self.contract = w3.eth.contract(abi=abi, address=address) - self.w3 = w3 - if signer_address != None: - self.signer_address = signer_address - else: - if type(self.w3.eth.defaultAccount).__name__ == 'Empty': - self.w3.eth.defaultAccount = self.w3.eth.accounts[0] - self.signer_address = self.w3.eth.defaultAccount - - - @staticmethod - def abi(): - if TransferApproval.__abi == None: - f = open(os.path.join(datadir, 'TransferApproval.json'), 'r') - TransferApproval.__abi = json.load(f) - f.close() - return TransferApproval.__abi - - - @staticmethod - def bytecode(): - if TransferApproval.__bytecode == None: - f = open(os.path.join(datadir, 'TransferApproval.bin')) - TransferApproval.__bytecode = f.read() - f.close() - return TransferApproval.__bytecode - - - def last_serial(self): - return self.contract.functions.lastSerial().call() - - - def next_serial(self): - return self.contract.functions.nextSerial().call() - - - def requests(self, idx): - req = self.contract.functions.requests(idx).call() - return { - 'serial': req[0], - 'sender': req[1], - 'recipient': req[2], - 'token': req[3], - 'value': req[4], - } diff --git a/python/erc20_transfer_authorization/transfer_authorization.py b/python/erc20_transfer_authorization/transfer_authorization.py @@ -0,0 +1,134 @@ +# Author: Louis Holbrook <dev@holbrook.no> 0826EDA1702D1E87C6E2875121D2E7BB88C2A746 +# SPDX-License-Identifier: GPL-3.0-or-later +# File-version: 1 +# Description: Python interface to abi and bin files for faucet contracts + +# standard imports +import logging +import json +import os + +# external imports +from chainlib.eth.tx import TxFactory +from chainlib.eth.constant import ZERO_ADDRESS +from chainlib.eth.contract import ( + ABIContractEncoder, + ABIContractDecoder, + ABIContractType, + abi_decode_single, + ) +from chainlib.jsonrpc import jsonrpc_template +from hexathon import add_0x + +logg = logging.getLogger().getChild(__name__) + +moddir = os.path.dirname(__file__) +datadir = os.path.join(moddir, 'data') + + +class TransferAuthorization(TxFactory): + + __abi = None + __bytecode = None + + + @staticmethod + def abi(): + if TransferAuthorization.__abi == None: + f = open(os.path.join(datadir, 'ERC20TransferAuthorization.json'), 'r') + TransferAuthorization.__abi = json.load(f) + f.close() + return TransferAuthorization.__abi + + + @staticmethod + def bytecode(): + if TransferAuthorization.__bytecode == None: + f = open(os.path.join(datadir, 'ERC20TransferAuthorization.bin')) + TransferAuthorization.__bytecode = f.read() + f.close() + return TransferAuthorization.__bytecode + + + def constructor(self, sender_address): + code = TransferAuthorization.bytecode() + tx = self.template(sender_address, None, use_nonce=True) + tx = self.set_code(tx, code) + return self.build(tx) + + + def signers(self, contract_address, signer_address, sender_address=ZERO_ADDRESS): + o = jsonrpc_template() + o['method'] = 'eth_call' + enc = ABIContractEncoder() + enc.method('signers') + enc.typ(ABIContractType.ADDRESS) + enc.address(signer_address) + data = add_0x(enc.get()) + tx = self.template(sender_address, contract_address) + tx = self.set_code(tx, data) + o['params'].append(self.normalize(tx)) + o['params'].append('latest') + return o + + + def have_signer(self, contract_address, signer_address, sender_address=ZERO_ADDRESS): + return self.signers(contract_address, signer_address, sender_address) + + + @classmethod + def parse_signers(self, v): + return abi_decode_single(ABIContractType.BOOLEAN, v) + + + @classmethod + def parse_create_request_request(self, v): + v = strip_0x(v) + cursor = 0 + enc = ABIContractEncoder() + enc.method('createRequest') + enc.typ(ABIContractType.ADDRESS) + enc.typ(ABIContractType.ADDRESS) + enc.typ(ABIContractType.ADDRESS) + enc.typ(ABIContractType.UINT256) + r = enc.get() + l = len(r) + m = v[:l] + if m != r: + logg.error('method mismatch, expected {}, got {}'.format(r, m)) + raise RequestMismatchException(v) + cursor += l + + dec = ABIContractDecoder() + dec.typ(ABIContractType.ADDRESS) + dec.typ(ABIContractType.ADDRESS) + dec.typ(ABIContractType.ADDRESS) + dec.typ(ABIContractType.UINT256) + dec.val(v[cursor:cursor+64]) + cursor += 64 + dec.val(v[cursor:cursor+64]) + cursor += 64 + dec.val(v[cursor:cursor+64]) + cursor += 64 + dec.val(v[cursor:cursor+64]) + r = dec.decode() + return r + +# +# def last_serial(self): +# return self.contract.functions.lastSerial().call() +# +# +# def next_serial(self): +# return self.contract.functions.nextSerial().call() +# +# +# def requests(self, idx): +# req = self.contract.functions.requests(idx).call() +# return { +# 'serial': req[0], +# 'sender': req[1], +# 'recipient': req[2], +# 'token': req[3], +# 'value': req[4], +# } diff --git a/python/requirements.txt b/python/requirements.txt @@ -1,2 +1,2 @@ -web3==5.12.2 -crypto-dev-signer==0.4.13rc3 +crypto-dev-signer==0.4.13rc4 +chainlib==0.0.1a27 diff --git a/python/setup.cfg b/python/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = erc20-transfer-authorization -version = 0.3.0a11 +version = 0.3.1a1 description = Simple approval escrow for ERC20 spend approval author = Louis Holbrook author_email = dev@holbrook.no @@ -28,8 +28,8 @@ packages = erc20_transfer_authorization.runnable install_requires = web3==5.12.2 - crypto-dev-signer~=0.4.13rc2 - chainlib~=0.0.1a15 + crypto-dev-signer~=0.4.13rc4 + chainlib~=0.0.1a27 [options.package_data] * = diff --git a/python/test_requirements.txt b/python/test_requirements.txt @@ -1,2 +1,3 @@ -eth-tester==0.5.0b2 +eth-tester==0.5.0b3 py-evm==0.3.0a20 +#giftable-erc20-token==0.0.7b13 diff --git a/python/tests/base.py b/python/tests/base.py @@ -1,11 +1,17 @@ +# standard imports import os import unittest import json import logging -import web3 -import eth_tester -import eth_abi +# 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() @@ -16,56 +22,28 @@ logging.getLogger('eth.vm').setLevel(logging.WARNING) testdir = os.path.dirname(__file__) -class TestBase(unittest.TestCase): - - contract = None +class TestBase(EthTesterCase): def setUp(self): - eth_params = eth_tester.backends.pyevm.main.get_default_genesis_params({ - 'gas_limit': 9000000, - }) - - f = open(os.path.join(testdir, '../erc20_transfer_authorization/data/ERC20TransferAuthorization.bin'), 'r') - bytecode = f.read() - f.close() - - f = open(os.path.join(testdir, '../erc20_transfer_authorization/data/ERC20TransferAuthorization.json'), 'r') - self.abi_wallet = json.load(f) - f.close() - - backend = eth_tester.PyEVMBackend(eth_params) - self.eth_tester = eth_tester.EthereumTester(backend) - provider = web3.Web3.EthereumTesterProvider(self.eth_tester) - self.w3 = web3.Web3(provider) - c = self.w3.eth.contract(abi=self.abi_wallet, bytecode=bytecode) - tx_hash = c.constructor().transact({'from': self.w3.eth.accounts[0]}) - - r = self.w3.eth.getTransactionReceipt(tx_hash) - - self.address_wallet = r.contractAddress - - - f = open(os.path.join(testdir, '../erc20_transfer_authorization/data/GiftableToken.bin'), 'r') - bytecode = f.read() - f.close() - - f = open(os.path.join(testdir, '../erc20_transfer_authorization/data/GiftableToken.json'), 'r') - self.abi_token = json.load(f) - f.close() + 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]) - c = self.w3.eth.contract(abi=self.abi_token, bytecode=bytecode) - tx_hash = c.constructor('Foo Token', 'FOO', 18).transact({'from': self.w3.eth.accounts[0]}) + self.rpc.do(o) - r = self.w3.eth.getTransactionReceipt(tx_hash) + o = receipt(tx_hash_hex) + r = self.rpc.do(o) + self.assertEqual(r['status'], 1) - self.address_token = r.contractAddress - c = self.w3.eth.contract(abi=self.abi_token, address=self.address_token) + self.address = r['contract_address'] - tx_hash = c.functions.mint(1000).transact({'from': self.w3.eth.accounts[0]}) - tx_hash = c.functions.transfer(self.w3.eth.accounts[1], 100).transact({'from': self.w3.eth.accounts[0]}) - tx_hash = c.functions.transfer(self.w3.eth.accounts[2], 100).transact({'from': self.w3.eth.accounts[0]}) - tx_hash = c.functions.transfer(self.w3.eth.accounts[4], 100).transact({'from': self.w3.eth.accounts[0]}) + 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) - def tearDown(self): - pass + self.token_address = r['contract_address'] diff --git a/python/tests/test_app.py b/python/tests/test_app.py @@ -3,6 +3,12 @@ import os import unittest import logging +# external imports +from chainlib.eth.nonce import RPCNonceOracle + +# local imports +from erc20_transfer_authorization import TransferAuthorization + # testutil imports from tests.base import TestBase @@ -14,137 +20,145 @@ testdir = os.path.dirname(__file__) class ERC20TransferAuthorizationBasicTest(TestBase): def test_basic(self): - c = self.w3.eth.contract(abi=self.abi_wallet, address=self.address_wallet) - self.assertTrue(c.functions.signers(self.w3.eth.accounts[0]).call()) - self.assertFalse(c.functions.signers(self.w3.eth.accounts[1]).call()) - - - def test_get(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) - - tx_hash = w.functions.createRequest(self.w3.eth.accounts[2], self.w3.eth.accounts[3], t.address, 10).transact({'from': self.w3.eth.accounts[9]}) - r = self.w3.eth.getTransactionReceipt(tx_hash) - - topic_match = 'b609ae609609ee99268d05bc1371102cafe8d6b964bf082439ab16be2a01c87c' - log = r.logs[0] - topic = log.topics[0] - self.assertEqual(topic.hex()[2:], topic_match) - serial = int(log.data[66:], 16) - - for i in range(1, 3): - tx_hash = w.functions.createRequest(self.w3.eth.accounts[2], self.w3.eth.accounts[3+i], t.address, 10*(i+1)).transact({'from': self.w3.eth.accounts[2]}) - - tq_count = w.functions.count().call() - assert (tq_count == 3); - - for i in range(w.functions.nextSerial().call(), w.functions.lastSerial().call()): - tqg = w.functions.requests(i).call() - - self.assertEqual(tqg[0], i) - self.assertEqual(tqg[1], self.w3.eth.accounts[2]) - self.assertEqual(tqg[2], self.w3.eth.accounts[3+(i-1)]) - self.assertEqual(tqg[3], t.address) - self.assertEqual(tqg[4], 10*i) - - - def test_get_vote(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) - - tx_hash = w.functions.createRequest(self.w3.eth.accounts[2], self.w3.eth.accounts[3], t.address, 10).transact({'from': self.w3.eth.accounts[9]}) - w.functions.nay(1).transact({'from': self.w3.eth.accounts[0]}) - - self.assertEqual(w.functions.voters(1, 0).call(), self.w3.eth.accounts[0]) - self.assertEqual(w.functions.vote(1, self.w3.eth.accounts[0]).call(), -1) - - - def test_indexes(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) - - for i in range(0, 5): - amount = 10*(i+1) - sender = self.w3.eth.accounts[3+i]; - tx_hash = w.functions.createRequest(self.w3.eth.accounts[2], sender, t.address, amount).transact({'from': self.w3.eth.accounts[2]}) - - w.functions.nay(1).transact({'from': self.w3.eth.accounts[0]}) - w.functions.nay(4).transact({'from': self.w3.eth.accounts[0]}) - - self.assertEqual(w.functions.getSerialAt(0).call(), 2) - self.assertEqual(w.functions.getSerialAt(1).call(), 3) - self.assertEqual(w.functions.getSerialAt(2).call(), 5) - - - def test_index_after_removal(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) - - for i in range(0, 4): - amount = 10*(i+1) - sender = self.w3.eth.accounts[3+i]; - tx_hash = w.functions.createRequest(self.w3.eth.accounts[2], sender, t.address, amount).transact({'from': self.w3.eth.accounts[2]}) - - tq_count = w.functions.count().call() - self.assertEqual(tq_count, 4); - self.assertEqual(w.functions.lastSerial().call(), 4) - self.assertEqual(w.functions.nextSerial().call(), 1) - - w.functions.nay(2).transact({'from': self.w3.eth.accounts[0]}) - self.assertEqual(w.functions.count().call(), 3) - self.assertEqual(w.functions.nextSerial().call(), 1) - self.assertEqual(w.functions.lastSerial().call(), 4) - - w.functions.nay(1).transact({'from': self.w3.eth.accounts[0]}) - self.assertEqual(w.functions.count().call(), 2) - self.assertEqual(w.functions.nextSerial().call(), 3) - self.assertEqual(w.functions.lastSerial().call(), 4) - - w.functions.createRequest(self.w3.eth.accounts[2], self.w3.eth.accounts[3], t.address, 42).transact({'from': self.w3.eth.accounts[2]}) - self.assertEqual(w.functions.count().call(), 3) - self.assertEqual(w.functions.lastSerial().call(), 5) - self.assertEqual(w.functions.nextSerial().call(), 3) - - w.functions.nay(3).transact({'from': self.w3.eth.accounts[0]}) - self.assertEqual(w.functions.count().call(), 2) - self.assertEqual(w.functions.lastSerial().call(), 5) - self.assertEqual(w.functions.nextSerial().call(), 4) - - w.functions.nay(4).transact({'from': self.w3.eth.accounts[0]}) - self.assertEqual(w.functions.count().call(), 1) - self.assertEqual(w.functions.nextSerial().call(), 5) - self.assertEqual(w.functions.lastSerial().call(), 5) - - w.functions.nay(5).transact({'from': self.w3.eth.accounts[0]}) - self.assertEqual(w.functions.count().call(), 0) - self.assertEqual(w.functions.nextSerial().call(), 0) - self.assertEqual(w.functions.lastSerial().call(), 5) - - - def test_pass_on_insufficient_approve(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) - - self.eth_tester.mine_block() - - w.functions.createRequest(self.w3.eth.accounts[2], self.w3.eth.accounts[3], t.address, 10).transact({'from': self.w3.eth.accounts[2]}) - w.functions.yay(1).transact({'from': self.w3.eth.accounts[0]}) - self.eth_tester.mine_block() - - tx_hash = w.functions.executeRequest(1).transact({'from': self.w3.eth.accounts[0]}) - - r = self.w3.eth.getTransactionReceipt(tx_hash) - - topic_match = 'dab20a0fcd702cf875c2d715d5c3fc99af66a716c94b3405408c94b7311c99eb' # TransferFail(uint256) - log = r.logs[0] - topic = log.topics[0] - self.assertEqual(topic.hex()[2:], topic_match) - serial = int(log.data[2:], 16) - - self.assertEqual(serial, 1) - - self.assertEqual(w.functions.count().call(), 0) - self.assertEqual(w.functions.nextSerial().call(), 0) + + nonce_oracle = RPCNonceOracle(self.accounts[0], self.rpc) + c = TransferAuthorization(chain_id=self.chain_spec.chain_id()) + + o = c.signers(self.address, self.accounts[0], sender_address=self.accounts[0]) + r = self.rpc.do(o) + self.assertTrue(c.parse_signers(r)) + + o = c.signers(self.address, self.accounts[1], sender_address=self.accounts[0]) + r = self.rpc.do(o) + self.assertFalse(c.parse_signers(r)) + + +# def test_get(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) +# +# tx_hash = w.functions.createRequest(self.w3.eth.accounts[2], self.w3.eth.accounts[3], t.address, 10).transact({'from': self.w3.eth.accounts[9]}) +# r = self.w3.eth.getTransactionReceipt(tx_hash) +# +# topic_match = 'b609ae609609ee99268d05bc1371102cafe8d6b964bf082439ab16be2a01c87c' +# log = r.logs[0] +# topic = log.topics[0] +# self.assertEqual(topic.hex()[2:], topic_match) +# serial = int(log.data[66:], 16) +# +# for i in range(1, 3): +# tx_hash = w.functions.createRequest(self.w3.eth.accounts[2], self.w3.eth.accounts[3+i], t.address, 10*(i+1)).transact({'from': self.w3.eth.accounts[2]}) +# +# tq_count = w.functions.count().call() +# assert (tq_count == 3); +# +# for i in range(w.functions.nextSerial().call(), w.functions.lastSerial().call()): +# tqg = w.functions.requests(i).call() +# +# self.assertEqual(tqg[0], i) +# self.assertEqual(tqg[1], self.w3.eth.accounts[2]) +# self.assertEqual(tqg[2], self.w3.eth.accounts[3+(i-1)]) +# self.assertEqual(tqg[3], t.address) +# self.assertEqual(tqg[4], 10*i) +# +# +# def test_get_vote(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) +# +# tx_hash = w.functions.createRequest(self.w3.eth.accounts[2], self.w3.eth.accounts[3], t.address, 10).transact({'from': self.w3.eth.accounts[9]}) +# w.functions.nay(1).transact({'from': self.w3.eth.accounts[0]}) +# +# self.assertEqual(w.functions.voters(1, 0).call(), self.w3.eth.accounts[0]) +# self.assertEqual(w.functions.vote(1, self.w3.eth.accounts[0]).call(), -1) +# +# +# def test_indexes(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) +# +# for i in range(0, 5): +# amount = 10*(i+1) +# sender = self.w3.eth.accounts[3+i]; +# tx_hash = w.functions.createRequest(self.w3.eth.accounts[2], sender, t.address, amount).transact({'from': self.w3.eth.accounts[2]}) +# +# w.functions.nay(1).transact({'from': self.w3.eth.accounts[0]}) +# w.functions.nay(4).transact({'from': self.w3.eth.accounts[0]}) +# +# self.assertEqual(w.functions.getSerialAt(0).call(), 2) +# self.assertEqual(w.functions.getSerialAt(1).call(), 3) +# self.assertEqual(w.functions.getSerialAt(2).call(), 5) +# +# +# def test_index_after_removal(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) +# +# for i in range(0, 4): +# amount = 10*(i+1) +# sender = self.w3.eth.accounts[3+i]; +# tx_hash = w.functions.createRequest(self.w3.eth.accounts[2], sender, t.address, amount).transact({'from': self.w3.eth.accounts[2]}) +# +# tq_count = w.functions.count().call() +# self.assertEqual(tq_count, 4); +# self.assertEqual(w.functions.lastSerial().call(), 4) +# self.assertEqual(w.functions.nextSerial().call(), 1) +# +# w.functions.nay(2).transact({'from': self.w3.eth.accounts[0]}) +# self.assertEqual(w.functions.count().call(), 3) +# self.assertEqual(w.functions.nextSerial().call(), 1) +# self.assertEqual(w.functions.lastSerial().call(), 4) +# +# w.functions.nay(1).transact({'from': self.w3.eth.accounts[0]}) +# self.assertEqual(w.functions.count().call(), 2) +# self.assertEqual(w.functions.nextSerial().call(), 3) +# self.assertEqual(w.functions.lastSerial().call(), 4) +# +# w.functions.createRequest(self.w3.eth.accounts[2], self.w3.eth.accounts[3], t.address, 42).transact({'from': self.w3.eth.accounts[2]}) +# self.assertEqual(w.functions.count().call(), 3) +# self.assertEqual(w.functions.lastSerial().call(), 5) +# self.assertEqual(w.functions.nextSerial().call(), 3) +# +# w.functions.nay(3).transact({'from': self.w3.eth.accounts[0]}) +# self.assertEqual(w.functions.count().call(), 2) +# self.assertEqual(w.functions.lastSerial().call(), 5) +# self.assertEqual(w.functions.nextSerial().call(), 4) +# +# w.functions.nay(4).transact({'from': self.w3.eth.accounts[0]}) +# self.assertEqual(w.functions.count().call(), 1) +# self.assertEqual(w.functions.nextSerial().call(), 5) +# self.assertEqual(w.functions.lastSerial().call(), 5) +# +# w.functions.nay(5).transact({'from': self.w3.eth.accounts[0]}) +# self.assertEqual(w.functions.count().call(), 0) +# self.assertEqual(w.functions.nextSerial().call(), 0) +# self.assertEqual(w.functions.lastSerial().call(), 5) +# +# +# def test_pass_on_insufficient_approve(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) +# +# self.eth_tester.mine_block() +# +# w.functions.createRequest(self.w3.eth.accounts[2], self.w3.eth.accounts[3], t.address, 10).transact({'from': self.w3.eth.accounts[2]}) +# w.functions.yay(1).transact({'from': self.w3.eth.accounts[0]}) +# self.eth_tester.mine_block() +# +# tx_hash = w.functions.executeRequest(1).transact({'from': self.w3.eth.accounts[0]}) +# +# r = self.w3.eth.getTransactionReceipt(tx_hash) +# +# topic_match = 'dab20a0fcd702cf875c2d715d5c3fc99af66a716c94b3405408c94b7311c99eb' # TransferFail(uint256) +# log = r.logs[0] +# topic = log.topics[0] +# self.assertEqual(topic.hex()[2:], topic_match) +# serial = int(log.data[2:], 16) +# +# self.assertEqual(serial, 1) +# +# self.assertEqual(w.functions.count().call(), 0) +# self.assertEqual(w.functions.nextSerial().call(), 0) if __name__ == '__main__':