Esempio n. 1
0
def test_send_same_function_call_twice_without_nonce_tracking(
        each_identity, test_contract, delegate):
    """Test that we can send two similar transactions to a contract by selecting a random nonce > 2**255"""
    to = test_contract.address
    argument = 10
    function_call = test_contract.functions.testFunction(argument)

    max_nonce = 2**255
    random_gap = 123456

    meta_transaction = MetaTransaction.from_function_call(function_call,
                                                          to=to,
                                                          nonce=max_nonce)
    meta_transaction = each_identity.filled_and_signed_meta_transaction(
        meta_transaction)
    delegate.send_signed_meta_transaction(meta_transaction)

    meta_transaction = MetaTransaction.from_function_call(function_call,
                                                          to=to,
                                                          nonce=max_nonce +
                                                          random_gap)
    meta_transaction = each_identity.filled_and_signed_meta_transaction(
        meta_transaction)
    delegate.send_signed_meta_transaction(meta_transaction)

    events = test_contract.events.TestEvent.createFilter(
        fromBlock=0).get_all_entries()

    for event in events:
        assert event["args"]["from"] == each_identity.address
        assert event["args"]["value"] == 0
        assert event["args"]["argument"] == argument
Esempio n. 2
0
def test_validate_valid_nonce_increase(each_identity, delegate, accounts):
    to = accounts[2]
    value = 1000

    meta_transaction1 = each_identity.filled_and_signed_meta_transaction(
        MetaTransaction(to=to, value=value, nonce=1))
    meta_transaction2 = each_identity.filled_and_signed_meta_transaction(
        MetaTransaction(to=to, value=value, nonce=2))

    delegate.send_signed_meta_transaction(meta_transaction1)

    assert delegate.validate_meta_transaction(meta_transaction2)
Esempio n. 3
0
def test_next_nonce(each_identity, delegate, accounts):
    to = accounts[2]
    value = 1000

    meta_transaction1 = each_identity.filled_and_signed_meta_transaction(
        MetaTransaction(to=to, value=value, nonce=1))
    meta_transaction2 = each_identity.filled_and_signed_meta_transaction(
        MetaTransaction(to=to, value=value, nonce=2))

    delegate.send_signed_meta_transaction(meta_transaction1)
    delegate.send_signed_meta_transaction(meta_transaction2)

    assert delegate.get_next_nonce(each_identity.address) == 3
Esempio n. 4
0
def test_delegated_transaction_invalid_nonce(identity, delegate, accounts):
    to = accounts[2]
    value = 1000

    meta_transaction1 = identity.filled_and_signed_meta_transaction(
        MetaTransaction(to=to, value=value, nonce=1))
    meta_transaction2 = identity.filled_and_signed_meta_transaction(
        MetaTransaction(to=to, value=value, nonce=1))

    delegate.send_signed_meta_transaction(meta_transaction1)

    with pytest.raises(InvalidMetaTransactionException):
        delegate.send_signed_meta_transaction(meta_transaction2)
Esempio n. 5
0
def test_delegated_transaction_nonce_gap_fails(each_identity, delegate, web3,
                                               accounts):
    to = accounts[2]
    value = 1000

    meta_transaction1 = each_identity.filled_and_signed_meta_transaction(
        MetaTransaction(to=to, value=value, nonce=1))
    meta_transaction2 = each_identity.filled_and_signed_meta_transaction(
        MetaTransaction(to=to, value=value, nonce=3))

    delegate.send_signed_meta_transaction(meta_transaction1)

    with pytest.raises(TransactionFailed):
        delegate.send_signed_meta_transaction(meta_transaction2)
Esempio n. 6
0
def test_meta_transaction_fee_recipient(currency_network_contract,
                                        each_identity, delegate,
                                        delegate_address, accounts):
    A = each_identity.address
    B = accounts[3]
    to = currency_network_contract.address
    base_fee = 123

    function_call = currency_network_contract.functions.updateCreditlimits(
        B, 100, 100)
    meta_transaction = MetaTransaction.from_function_call(function_call,
                                                          to=to,
                                                          base_fee=base_fee)
    meta_transaction = attr.evolve(meta_transaction, fee_recipient=B)
    meta_transaction = each_identity.filled_and_signed_meta_transaction(
        meta_transaction)
    delegate.send_signed_meta_transaction(meta_transaction)

    debt_A_B = currency_network_contract.functions.getDebt(A, B).call()
    debt_A_delegate = currency_network_contract.functions.getDebt(
        A, delegate_address).call()

    assert debt_A_B == base_fee
    assert debt_A_delegate == 0

    fee_payment_event = each_identity.contract.events.FeePayment().getLogs(
    )[-1]
    assert fee_payment_event["args"]["value"] == base_fee
    assert fee_payment_event["args"]["recipient"] == B
Esempio n. 7
0
def test_delegated_transaction_hash(each_identity_contract, test_contract,
                                    accounts):
    to = accounts[3]
    from_ = each_identity_contract.address
    argument = 10
    function_call = test_contract.functions.testFunction(argument)

    meta_transaction = MetaTransaction.from_function_call(function_call,
                                                          from_=from_,
                                                          to=to,
                                                          nonce=0)

    hash_by_contract = each_identity_contract.functions.transactionHash(
        meta_transaction.to,
        meta_transaction.value,
        meta_transaction.data,
        meta_transaction.base_fee,
        meta_transaction.gas_price,
        meta_transaction.gas_limit,
        meta_transaction.fee_recipient,
        meta_transaction.currency_network_of_fees,
        meta_transaction.nonce,
        meta_transaction.time_limit,
        meta_transaction.operation_type.value,
    ).call()

    hash = meta_transaction.hash

    assert hash == HexBytes(hash_by_contract)
Esempio n. 8
0
def test_proxy_overhead(web3, table, test_contract, proxied_identity, identity,
                        delegate):
    """Tests the overhead of using an identity proxy compared to a regular identity"""

    to = test_contract.address
    argument = 10
    function_call = test_contract.functions.testFunction(argument)

    meta_transaction = MetaTransaction.from_function_call(function_call, to=to)
    proxied_meta_transaction = proxied_identity.filled_and_signed_meta_transaction(
        meta_transaction)
    not_proxied_meta_transaction = identity.filled_and_signed_meta_transaction(
        meta_transaction)
    proxied_meta_tx_id = delegate.send_signed_meta_transaction(
        proxied_meta_transaction)
    not_proxied_meta_tx_id = delegate.send_signed_meta_transaction(
        not_proxied_meta_transaction)

    gas_cost_proxied_meta_tx = get_gas_costs(web3, proxied_meta_tx_id)
    gas_cost_not_proxied_tx = get_gas_costs(web3, not_proxied_meta_tx_id)

    overhead = gas_cost_proxied_meta_tx - gas_cost_not_proxied_tx

    report_gas_costs(table,
                     "Overhead of a proxy over non-proxy meta-tx",
                     overhead,
                     limit=1500)
Esempio n. 9
0
def test_meta_tx_over_regular_tx_overhead(
    web3, gas_values_snapshot, test_contract, identity, delegate
):
    """Tests the overhead of using a meta-tx compared to a regular tx"""
    # The test sends two meta-tx as the first meta-tx of an identity is more expensive than all the next ones
    # due to storage allocation

    to = test_contract.address
    argument = 10
    function_call = test_contract.functions.testFunction(argument)

    # first meta-tx
    meta_transaction = MetaTransaction.from_function_call(function_call, to=to)
    filled_meta_tx = identity.filled_and_signed_meta_transaction(meta_transaction)
    delegate.send_signed_meta_transaction(filled_meta_tx)

    # second meta-tx we meter
    second_filled_meta_transaction = identity.filled_and_signed_meta_transaction(
        meta_transaction
    )
    meta_tx_id = delegate.send_signed_meta_transaction(second_filled_meta_transaction)
    regular_tx_id = test_contract.functions.testFunction(argument).transact()

    gas_cost_meta_tx = get_gas_costs(web3, meta_tx_id)
    gas_cost_regular_tx = get_gas_costs(web3, regular_tx_id)

    overhead = gas_cost_meta_tx - gas_cost_regular_tx

    gas_values_snapshot.assert_gas_costs_match(
        "UNPROXIED_META_TRANSACTION_OVERHEAD", overhead
    )
Esempio n. 10
0
def test_meta_transaction_create_contract_fails(each_identity, delegate,
                                                non_payable_contract_inticode,
                                                web3, operation_type):
    """Test that the status in the event is False when deployment fails"""
    # To make the deployment fail we deploy a contract whose constructor is not payable
    # and transfer it eth during deployment
    deployed_contract_balance = 123
    meta_transaction = MetaTransaction(
        operation_type=operation_type,
        data=non_payable_contract_inticode,
        value=deployed_contract_balance,
    )
    meta_transaction = each_identity.filled_and_signed_meta_transaction(
        meta_transaction)
    tx_id = delegate.send_signed_meta_transaction(meta_transaction)

    execution_event = each_identity.contract.events.TransactionExecution.createFilter(
        fromBlock=0).get_all_entries()[0]["args"]

    # assert that the create failed
    assert get_transaction_status(web3, tx_id)
    assert execution_event["hash"] == meta_transaction.hash
    assert execution_event["status"] is False

    deploy_events = each_identity.contract.events.ContractDeployment.createFilter(
        fromBlock=0).get_all_entries()
    assert len(deploy_events) == 0
Esempio n. 11
0
def test_meta_tx_over_own_identity_tx_overhead(web3, table, test_contract,
                                               identity, owner, delegate):
    """Tests the overhead of using a meta-tx compared to an owned identity tx"""
    # The test sends two meta-tx as the first meta-tx of an identity is more expensive than all the next ones
    # due to storage allocation

    to = test_contract.address
    argument = 10
    function_call = test_contract.functions.testFunction(argument)

    # first meta-tx
    meta_transaction = MetaTransaction.from_function_call(function_call, to=to)
    filled_meta_tx = identity.filled_and_signed_meta_transaction(
        meta_transaction)
    delegate.send_signed_meta_transaction(filled_meta_tx)

    # second meta-tx we meter
    second_filled_meta_transaction = identity.filled_and_signed_meta_transaction(
        meta_transaction)
    meta_tx_id = delegate.send_signed_meta_transaction(
        second_filled_meta_transaction)
    owner_tx_id = identity.contract.functions.execute(
        to, 0, meta_transaction.data, 0, 0).transact({"from": owner})

    gas_cost_meta_tx = get_gas_costs(web3, meta_tx_id)
    gas_cost_owner_tx = get_gas_costs(web3, owner_tx_id)

    overhead = gas_cost_meta_tx - gas_cost_owner_tx

    report_gas_costs(
        table,
        "Overhead of unproxied meta-tx over owned transaction",
        overhead,
        limit=22000,
    )
Esempio n. 12
0
def test_delegated_transaction_wrong_from(each_identity_contract,
                                          delegate_address, accounts,
                                          owner_key, chain_id):
    from_ = accounts[3]
    to = accounts[2]
    value = 1000

    meta_transaction = MetaTransaction(from_=from_,
                                       to=to,
                                       value=value,
                                       nonce=0,
                                       chain_id=chain_id).signed(owner_key)

    with pytest.raises(TransactionFailed):
        each_identity_contract.functions.executeTransaction(
            meta_transaction.to,
            meta_transaction.value,
            meta_transaction.data,
            meta_transaction.base_fee,
            meta_transaction.gas_price,
            meta_transaction.gas_limit,
            meta_transaction.fee_recipient,
            meta_transaction.currency_network_of_fees,
            meta_transaction.nonce,
            meta_transaction.time_limit,
            meta_transaction.operation_type.value,
            meta_transaction.signature,
        ).transact({"from": delegate_address})
Esempio n. 13
0
def test_own_identity_meta_tx_overhead(web3, table, test_contract, identity,
                                       owner, delegate):
    """Tests the overhead of using an owned meta-tx compared to a regular tx"""

    to = test_contract.address
    argument = 10
    function_call = test_contract.functions.testFunction(argument)

    meta_transaction = MetaTransaction.from_function_call(function_call, to=to)
    owner_tx_id = identity.contract.functions.execute(
        to, 0, meta_transaction.data, 0, 0).transact({"from": owner})

    regular_tx_id = test_contract.functions.testFunction(argument).transact()

    gas_cost_owner_meta_tx = get_gas_costs(web3, owner_tx_id)
    gas_cost_regular_tx = get_gas_costs(web3, regular_tx_id)

    overhead = gas_cost_owner_meta_tx - gas_cost_regular_tx

    report_gas_costs(
        table,
        "Overhead of owned unproxied meta-tx over regular transaction",
        overhead,
        limit=5000,
    )
Esempio n. 14
0
def test_tracking_delegation_fee_in_different_network(
    currency_network_contract,
    second_currency_network_contract,
    each_identity,
    delegate,
    delegate_address,
    accounts,
):
    A = each_identity.address
    B = accounts[3]
    to = currency_network_contract.address
    base_fee = 123

    function_call = currency_network_contract.functions.updateCreditlimits(
        B, 100, 100)
    meta_transaction = each_identity.filled_and_signed_meta_transaction(
        MetaTransaction.from_function_call(
            function_call,
            to=to,
            base_fee=base_fee,
            currency_network_of_fees=second_currency_network_contract.address,
        ))
    delegate.send_signed_meta_transaction(meta_transaction)

    assert currency_network_contract.functions.getDebt(
        A, delegate_address).call() == 0
    assert (second_currency_network_contract.functions.getDebt(
        A, delegate_address).call() == base_fee)
Esempio n. 15
0
def test_meta_tx_over_regular_tx_overhead(web3, table, test_contract, identity,
                                          delegate):
    """Tests the overhead of using a meta-tx compared to a regular tx"""
    # The test sends two meta-tx as the first meta-tx of an identity is more expensive than all the next ones
    # due to storage allocation

    to = test_contract.address
    argument = 10
    function_call = test_contract.functions.testFunction(argument)

    # first meta-tx
    meta_transaction = MetaTransaction.from_function_call(function_call, to=to)
    filled_meta_tx = identity.filled_and_signed_meta_transaction(
        meta_transaction)
    delegate.send_signed_meta_transaction(filled_meta_tx)

    # second meta-tx we meter
    second_filled_meta_transaction = identity.filled_and_signed_meta_transaction(
        meta_transaction)
    meta_tx_id = delegate.send_signed_meta_transaction(
        second_filled_meta_transaction)
    regular_tx_id = test_contract.functions.testFunction(argument).transact()

    gas_cost_meta_tx = get_gas_costs(web3, meta_tx_id)
    gas_cost_regular_tx = get_gas_costs(web3, regular_tx_id)

    overhead = gas_cost_meta_tx - gas_cost_regular_tx

    report_gas_costs(table,
                     "Overhead of unproxied meta-tx over regular tx",
                     overhead,
                     limit=26750)
Esempio n. 16
0
def test_proxy_overhead(
    web3, gas_values_snapshot, test_contract, proxied_identity, identity, delegate
):
    """Tests the overhead of using an identity proxy compared to a regular identity"""

    to = test_contract.address
    argument = 10
    function_call = test_contract.functions.testFunction(argument)

    meta_transaction = MetaTransaction.from_function_call(function_call, to=to)
    proxied_meta_transaction = proxied_identity.filled_and_signed_meta_transaction(
        meta_transaction
    )
    not_proxied_meta_transaction = identity.filled_and_signed_meta_transaction(
        meta_transaction
    )
    proxied_meta_tx_id = delegate.send_signed_meta_transaction(proxied_meta_transaction)
    not_proxied_meta_tx_id = delegate.send_signed_meta_transaction(
        not_proxied_meta_transaction
    )

    gas_cost_proxied_meta_tx = get_gas_costs(web3, proxied_meta_tx_id)
    gas_cost_not_proxied_tx = get_gas_costs(web3, not_proxied_meta_tx_id)

    overhead = gas_cost_proxied_meta_tx - gas_cost_not_proxied_tx

    gas_values_snapshot.assert_gas_costs_match(
        "PROXIED_META_TRANSACTION_OVERHEAD_OVER_NONPROXY_METATRANSACTION", overhead
    )
Esempio n. 17
0
def test_gas_pricing(delegate, delegate_config, gas_price_config, gas_price):
    config = dict(**delegate_config)
    config.update(gas_price_config)

    delegate.config = config

    assert delegate._calculate_gas_price(MetaTransaction()) == gas_price
Esempio n. 18
0
def test_meta_transaction_delegate_call(each_identity, delegate,
                                        delegate_address, web3, test_contract):
    to = test_contract.address
    argument = 123
    function_call = test_contract.functions.testFunction(argument)

    meta_transaction = MetaTransaction.from_function_call(function_call, to=to)
    meta_transaction = attr.evolve(
        meta_transaction,
        operation_type=MetaTransaction.OperationType.DELEGATE_CALL)
    meta_transaction = each_identity.filled_and_signed_meta_transaction(
        meta_transaction)
    tx_id = delegate.send_signed_meta_transaction(meta_transaction)

    execution_event = each_identity.contract.events.TransactionExecution.createFilter(
        fromBlock=0).get_all_entries()[0]["args"]

    # assert that the delegate call was successful
    assert get_transaction_status(web3, tx_id)
    assert execution_event["hash"] == meta_transaction.hash
    assert execution_event["status"] is True

    proxied_test_contract = web3.eth.contract(each_identity.contract.address,
                                              abi=test_contract.abi)
    test_event = proxied_test_contract.events.TestEvent.createFilter(
        fromBlock=0).get_all_entries()[0]["args"]

    # assert that the successful operation was indeed a delegate call
    # by checking that `from` is delegate_address and not identity_address
    assert test_event["from"] == delegate_address
    assert test_event["value"] == 0
    assert test_event["argument"] == argument
Esempio n. 19
0
def test_revoke_meta_transaction_nonce(each_identity, delegate, test_contract):
    """Test that we can revoke a meta-tx that uses nonce anti-replay mechanism via using the nonce"""
    to = test_contract.address
    argument = 10
    function_call = test_contract.functions.testFunction(argument)

    meta_transaction = each_identity.filled_and_signed_meta_transaction(
        MetaTransaction.from_function_call(function_call, to=to))

    revoke_meta_transaction = each_identity.filled_and_signed_meta_transaction(
        MetaTransaction(to=each_identity.address,
                        nonce=meta_transaction.nonce))
    delegate.send_signed_meta_transaction(revoke_meta_transaction)

    assert not delegate.validate_meta_transaction(meta_transaction)
    with pytest.raises(TransactionFailed):
        delegate.send_signed_meta_transaction(meta_transaction)
Esempio n. 20
0
    def transfer_meta_transaction(self, value, max_fee, path, extra_data=b""):

        function_call = self._proxy.functions.transfer(value, max_fee, path, extra_data)
        meta_transaction = MetaTransaction.from_function_call(
            function_call, to=self.address
        )

        return meta_transaction
Esempio n. 21
0
def test_validate_valid_transfer(each_identity, delegate, accounts):
    to = accounts[2]
    value = 1000

    meta_transaction = each_identity.filled_and_signed_meta_transaction(
        MetaTransaction(to=to, value=value))

    assert delegate.validate_meta_transaction(meta_transaction)
Esempio n. 22
0
def test_get_not_found_meta_transaction_status(each_identity, delegate):

    meta_transaction = each_identity.filled_and_signed_meta_transaction(
        MetaTransaction(to=each_identity.address))

    meta_tx_status = delegate.get_meta_transaction_status(
        each_identity.address, meta_transaction.hash)
    assert meta_tx_status == MetaTransactionStatus.NOT_FOUND
Esempio n. 23
0
def test_delegated_transaction_nonce_increase(each_identity, delegate, web3,
                                              accounts):
    to = accounts[2]
    value = 1000

    balance_before = web3.eth.getBalance(to)

    meta_transaction1 = each_identity.filled_and_signed_meta_transaction(
        MetaTransaction(to=to, value=value, nonce=1))
    meta_transaction2 = each_identity.filled_and_signed_meta_transaction(
        MetaTransaction(to=to, value=value, nonce=2))

    delegate.send_signed_meta_transaction(meta_transaction1)
    delegate.send_signed_meta_transaction(meta_transaction2)

    balance_after = web3.eth.getBalance(to)

    assert balance_after - balance_before == value + value
Esempio n. 24
0
def test_estimate_gas(each_identity, delegate, accounts):
    to = accounts[2]
    value = 1000

    meta_transaction = each_identity.filled_and_signed_meta_transaction(
        MetaTransaction(to=to, value=value))

    assert isinstance(
        delegate.estimate_gas_signed_meta_transaction(meta_transaction), int)
Esempio n. 25
0
def test_get_successful_meta_transaction_status(each_identity, delegate):

    meta_transaction = each_identity.filled_and_signed_meta_transaction(
        MetaTransaction(to=each_identity.address))

    delegate.send_signed_meta_transaction(meta_transaction)

    meta_tx_status = delegate.get_meta_transaction_status(
        each_identity.address, meta_transaction.hash)
    assert meta_tx_status == MetaTransactionStatus.SUCCESS
Esempio n. 26
0
    def _deserialize(self, value, attr, data, **kwargs):

        # deserialize into the OperationType enum instance corresponding to the value
        try:
            return MetaTransaction.OperationType(value)
        except ValueError:
            raise ValidationError(
                f"Could not parse attribute {attr}: {value} has to be one of "
                f"{[operation_type.value for operation_type in MetaTransaction.OperationType]}"
            )
Esempio n. 27
0
def test_cannot_revoke_executed_transaction(each_identity, delegate,
                                            test_contract):
    """Test that we can not revoke a meta-tx that was already executed"""
    to = test_contract.address
    argument = 10
    function_call = test_contract.functions.testFunction(argument)

    meta_transaction = each_identity.filled_and_signed_meta_transaction(
        MetaTransaction.from_function_call(function_call, to=to, nonce=0))
    delegate.send_signed_meta_transaction(meta_transaction)
    revoke_function_call = each_identity.contract.functions.cancelTransaction(
        meta_transaction.hash)
    revoke_meta_transaction = each_identity.filled_and_signed_meta_transaction(
        MetaTransaction.from_function_call(revoke_function_call,
                                           to=each_identity.address))
    delegate.send_signed_meta_transaction(revoke_meta_transaction)

    events = each_identity.contract.events.TransactionCancellation().getLogs()
    assert len(events) == 0
Esempio n. 28
0
def test_reveoke_meta_transaction_nonce_via_hash(each_identity, delegate,
                                                 test_contract):
    """Test that we can revoke a meta-tx that uses nonce anti-replay mechanism via canceling the hash"""
    to = test_contract.address
    argument = 10
    function_call = test_contract.functions.testFunction(argument)

    meta_transaction = each_identity.filled_and_signed_meta_transaction(
        MetaTransaction.from_function_call(function_call, to=to))

    revoke_function_call = each_identity.contract.functions.cancelTransaction(
        meta_transaction.hash)
    revoke_meta_transaction = each_identity.filled_and_signed_meta_transaction(
        MetaTransaction.from_function_call(revoke_function_call,
                                           to=each_identity.address))
    delegate.send_signed_meta_transaction(revoke_meta_transaction)

    assert not delegate.validate_meta_transaction(meta_transaction)
    with pytest.raises(SolidityError):
        delegate.send_signed_meta_transaction(meta_transaction)
Esempio n. 29
0
def test_delegated_transaction_same_tx_fails(each_identity, delegate, accounts,
                                             web3):
    to = accounts[2]
    value = 1000

    meta_transaction = MetaTransaction(to=to, value=value)
    meta_transaction = each_identity.filled_and_signed_meta_transaction(
        meta_transaction)
    delegate.send_signed_meta_transaction(meta_transaction)

    with pytest.raises(TransactionFailed):
        delegate.send_signed_meta_transaction(meta_transaction)
Esempio n. 30
0
def test_meta_transaction_gas_limit(each_identity, delegate, web3, accounts):
    to = accounts[2]
    value = 1000
    gas_limit = 456

    meta_transaction = MetaTransaction(to=to, value=value, gas_limit=gas_limit)

    meta_transaction = each_identity.filled_and_signed_meta_transaction(
        meta_transaction)

    with pytest.raises(TransactionFailed):
        delegate.send_signed_meta_transaction(meta_transaction)