Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug: Calls to empty accounts do not appear in tx.subcalls #1105

Closed
skellet0r opened this issue Jun 4, 2021 · 0 comments · Fixed by #1106
Closed

Bug: Calls to empty accounts do not appear in tx.subcalls #1105

skellet0r opened this issue Jun 4, 2021 · 0 comments · Fixed by #1106

Comments

@skellet0r
Copy link
Collaborator

Environment information

  • brownie Version: 1.14.6
  • ganache-cli Version: 6.12.2
  • solc Version: 0.8.4
  • Python Version: 3.8.9
  • OS: linux

What was wrong?

Low level calls to addresses which have no deployed contract do not show up in tx.subcalls.

Below is some example contracts in both solidity and vyper, as well as a sample set of test cases.

contracts/SolDummy.sol

// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0;

contract SolDummy {
    address constant TARGET = 0xD0660cD418a64a1d44E9214ad8e459324D8157f1;

    function foo_call() external {
        TARGET.call(abi.encodeWithSignature("bar()"));
    }

    function foo_static_call() external {
        TARGET.staticcall(abi.encodeWithSignature("bar()"));
    }

    function foo_delegate_call() external {
        TARGET.delegatecall(abi.encodeWithSignature("bar()"));
    }
}

contracts/VyDummy.vy

# @version 0.2.12


TARGET: constant(address) = 0xD0660cD418a64a1d44E9214ad8e459324D8157f1


@external
def foo_call():
    raw_call(TARGET, method_id("bar()"))


@external
def foo_static_call():
    raw_call(TARGET, method_id("bar()"), is_static_call=True)


@external
def foo_delegate_call():
    raw_call(TARGET, method_id("bar()"), is_delegate_call=True)

tests/test_call.py

import pytest


@pytest.fixture(scope="module")
def alice(accounts):
    return accounts[0]


@pytest.fixture(scope="module")
def sol_dummy(alice, SolDummy):
    return SolDummy.deploy({"from": alice})


@pytest.fixture(scope="module")
def vy_dummy(alice, VyDummy):
    return VyDummy.deploy({"from": alice})


@pytest.fixture(scope="module", params=(0, 1), ids=("SolDummy", "VyDummy"))
def dummy(request, sol_dummy, vy_dummy):
    return [sol_dummy, vy_dummy][request.param]


def test_call(alice, dummy):
    tx = dummy.foo_call({"from": alice})
    assert len(tx.subcalls) == 1


def test_static_call(alice, dummy):
    tx = dummy.foo_static_call.transact({"from": alice})
    assert len(tx.subcalls) == 1


def test_delegate_call(alice, dummy):
    tx = dummy.foo_delegate_call({"from": alice})
    assert len(tx.subcalls) == 1

When the above tests are ran, they all fail, when in fact they should pass as there is exactly 1 low level sub call in each of the dummy functions.

How can it be fixed?

This needs to be fixed in the brownie/network/transaction.py file, specifically in this area.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant