Skip to content

Commit

Permalink
fix: make always work when getting 1st time
Browse files Browse the repository at this point in the history
  • Loading branch information
antazoey committed Dec 12, 2024
1 parent 3413718 commit f939082
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 5 deletions.
6 changes: 6 additions & 0 deletions tests/functional/geth/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@
from tests.functional.data.python import TRACE_RESPONSE


@pytest.fixture(scope="session")
def safe_proxy_container(get_contract_type):
proxy_type = get_contract_type("SafeProxy")
return ContractContainer(proxy_type)


@pytest.fixture
def parity_trace_response():
return TRACE_RESPONSE
Expand Down
55 changes: 55 additions & 0 deletions tests/functional/geth/test_contracts_cache.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import pytest

from ape.exceptions import ContractNotFoundError
from tests.conftest import geth_process_test


@geth_process_test
def test_get_proxy_from_explorer(
mock_explorer,
create_mock_sepolia,
safe_proxy_container,
geth_account,
vyper_contract_container,
geth_provider,
chain,
):
"""
Simulated when you get a contract from Etherscan for the first time
but that contract is a proxy. We expect both proxy and target ABIs
to be cached under the proxy's address.
"""
target_contract = geth_account.deploy(vyper_contract_container, 10011339315)
proxy_contract = geth_account.deploy(safe_proxy_container, target_contract.address)

# Ensure both of these are not cached so we have to rely on our fake explorer.
del chain.contracts[target_contract.address]
del chain.contracts[proxy_contract.address]
# Sanity check.
with pytest.raises(ContractNotFoundError):
_ = chain.contracts.instance_at(proxy_contract.address)

def get_contract_type(address, *args, **kwargs):
# Mock etherscan backend.
if address == target_contract.address:
return target_contract.contract_type
elif address == proxy_contract.address:
return proxy_contract.contract_type

raise ValueError("Fake explorer only knows about proxy and target contracts.")

with create_mock_sepolia() as network:
# Setup our network to use our fake explorer.
mock_explorer.get_contract_type.side_effect = get_contract_type
network.__dict__["explorer"] = mock_explorer

# Typical flow: user attempts to get an un-cached contract type from Etherscan.
# That contract may be a proxy, in which case we should get a type
# w/ both proxy ABIs and the target ABIs.
contract_from_explorer = chain.contracts.instance_at(proxy_contract.address)

# Ensure we can call proxy methods!
assert contract_from_explorer.masterCopy # No attr error!

# Ensure we can call target methods!
assert contract_from_explorer.myNumber # No attr error!
6 changes: 2 additions & 4 deletions tests/functional/geth/test_proxy.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,10 @@ def test_uups_proxy(get_contract_type, geth_contract, owner, ethereum):


@geth_process_test
def test_gnosis_safe(get_contract_type, geth_contract, owner, ethereum, chain):
def test_gnosis_safe(safe_proxy_container, geth_contract, owner, ethereum, chain):
# Setup a proxy contract.
_type = get_contract_type("SafeProxy")
contract = ContractContainer(_type)
target = geth_contract.address
proxy_instance = owner.deploy(contract, target)
proxy_instance = owner.deploy(safe_proxy_container, target)

# (test)
actual = ethereum.get_proxy_info(proxy_instance.address)
Expand Down
5 changes: 4 additions & 1 deletion tests/functional/test_proxy.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,12 @@
"""


def test_minimal_proxy(ethereum, minimal_proxy):
def test_minimal_proxy(ethereum, minimal_proxy, chain):
actual = ethereum.get_proxy_info(minimal_proxy.address)
assert actual is not None
assert actual.type == ProxyType.Minimal
# It is the placeholder value still.
assert actual.target == "0xBEbeBeBEbeBebeBeBEBEbebEBeBeBebeBeBebebe"
# Show getting the contract using the proxy address.
contract = chain.contracts.instance_at(minimal_proxy.address)
assert contract.abi == [] # No target ABIs; no proxy ABIs either.

0 comments on commit f939082

Please sign in to comment.