Skip to content

Commit

Permalink
fix: handle not verified
Browse files Browse the repository at this point in the history
  • Loading branch information
antazoey committed Feb 2, 2024
1 parent 895c690 commit 7be1095
Show file tree
Hide file tree
Showing 8 changed files with 47 additions and 3 deletions.
4 changes: 4 additions & 0 deletions ape_etherscan/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

from ape_etherscan.config import EtherscanConfig
from ape_etherscan.exceptions import (
ContractNotVerifiedError,
UnhandledResultError,
UnsupportedEcosystemError,
UnsupportedNetworkError,
Expand Down Expand Up @@ -312,6 +313,9 @@ def get_source_code(self) -> SourceCodeResponse:
if not isinstance(data, dict):
raise UnhandledResultError(result, data)

if data.get("ABI") == "Contract source code not verified":
raise ContractNotVerifiedError(result, self._address)

return SourceCodeResponse.model_validate(data)

def verify_source_code(
Expand Down
4 changes: 4 additions & 0 deletions ape_etherscan/dependency.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from ape.api.projects import DependencyAPI
from ape.exceptions import ProjectError
from ape.types import AddressType
from ethpm_types import PackageManifest
from hexbytes import HexBytes
Expand Down Expand Up @@ -57,4 +58,7 @@ def extract_manifest(self, use_cache: bool = True) -> PackageManifest:
if ctx:
ctx.__exit__(None)

if not manifest:
raise ProjectError(f"Etherscan dependency '{self.name}' not verified.")

return manifest
9 changes: 9 additions & 0 deletions ape_etherscan/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,15 @@ def __init__(self, response: Union[Response, "EtherscanResponse"], message: str)
super().__init__(f"Response indicated failure: {message}")


class ContractNotVerifiedError(EtherscanResponseError):
"""
Raised when a contract is not verified on Etherscan.
"""

def __init__(self, response: Union[Response, "EtherscanResponse"], address: str):
super().__init__(response, f"Contract '{address}' not verified.")


class UnhandledResultError(EtherscanResponseError):
"""
Raised in specific client module where the result from Etherscan
Expand Down
15 changes: 12 additions & 3 deletions ape_etherscan/explorer.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
get_etherscan_api_uri,
get_etherscan_uri,
)
from ape_etherscan.exceptions import ContractNotVerifiedError
from ape_etherscan.types import EtherscanInstance
from ape_etherscan.verify import SourceVerifier

Expand Down Expand Up @@ -52,8 +53,12 @@ def _client_factory(self) -> ClientFactory:
)
)

def get_manifest(self, address: AddressType) -> PackageManifest:
response = self._get_source_code(address)
def get_manifest(self, address: AddressType) -> Optional[PackageManifest]:
try:
response = self._get_source_code(address)
except ContractNotVerifiedError:
return None

settings = {
"optimizer": {
"enabled": response.optimization_used,
Expand Down Expand Up @@ -99,7 +104,11 @@ def _get_source_code(self, address: AddressType) -> SourceCodeResponse:
return client.get_source_code()

def get_contract_type(self, address: AddressType) -> Optional[ContractType]:
source_code = self._get_source_code(address)
try:
source_code = self._get_source_code(address)
except ContractNotVerifiedError:
return None

contract_type = ContractType(abi=source_code.abi, contractName=source_code.name)
if source_code.name == "Vyper_contract" and "symbol" in contract_type.view_methods:
try:
Expand Down
1 change: 1 addition & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ def contract_address_map(address):
return {
"get_contract_response_flattened": address,
"get_contract_response_json": "0x000075Dc60EdE898f11b0d5C6cA31D7A6D050eeD",
"get_contract_response_not_verified": "0x5777d92f208679DB4b9778590Fa3CAB3aC9e2168",
"get_proxy_contract_response": "0x55A8a39bc9694714E2874c1ce77aa1E599461E18",
"get_vyper_contract_response": "0xdA816459F1AB5631232FE5e97a05BBBb94970c95",
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"status":"1","message":"OK","result":[{"SourceCode":"","ABI":"Contract source code not verified","ContractName":"","CompilerVersion":"","OptimizationUsed":"","Runs":"","ConstructorArguments":"","EVMVersion":"Default","Library":"","LicenseType":"Unknown","Proxy":"0","Implementation":"","SwarmSource":""}]}
15 changes: 15 additions & 0 deletions tests/test_dependency.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import pytest
from ape.exceptions import ProjectError

from ape_etherscan.dependency import EtherscanDependency

Expand All @@ -25,3 +26,17 @@ def test_dependency(mock_backend, verification_type, expected_name, contract_add
assert actual.compilers[0].name == "Solidity"
assert not actual.compilers[0].settings["optimizer"]["enabled"]
assert actual.compilers[0].contractTypes == [expected_name]


def test_dependency_not_verified(mock_backend):
mock_backend.set_network("ethereum", "mainnet")
mock_backend.setup_mock_get_contract_type_response("get_contract_response_not_verified")
dependency = EtherscanDependency(
name="Apes",
etherscan="0x5777d92f208679db4b9778590fa3cab3ac9e2168",
ecosystem="ethereum",
network="mainnet",
)
expected = "Etherscan dependency 'Apes' not verified."
with pytest.raises(ProjectError, match=expected):
dependency.extract_manifest()
1 change: 1 addition & 0 deletions tests/test_etherscan.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
EXPECTED_CONTRACT_NAME_MAP = {
"get_contract_response_flattened": "BoredApeYachtClub",
"get_contract_response_json": "BoredApeYachtClub",
"get_contract_response_not_verified": "",
"get_proxy_contract_response": "MIM-UST-f",
"get_vyper_contract_response": "yvDAI",
}
Expand Down

0 comments on commit 7be1095

Please sign in to comment.