Repository: eth-brownie/brownie
Issue: Cannot create `Contract` from etherscan contracts verified via JSON input

### What was wrong?

`Contract.from_explorer` fails when the source code is verified using the standard JSON input.

As an example: [0xaf1610D242c7CdD30c546844aF75c147C12e94F9](https://etherscan.io/address/0xaf1610D242c7CdD30c546844aF75c147C12e94F9#code)

```python
>>> Contract.from_explorer("0xaf1610D242c7CdD30c546844aF75c147C12e94F9") 
  File "<console>", line 1, in <module>
  File "eth_brownie-1.8.2-py3.8.egg/brownie/network/contract.py", line 440, in __init__
    contract = self.from_explorer(address, owner=owner, silent=True)
  File "eth_brownie-1.8.2-py3.8.egg/brownie/network/contract.py", line 651, in from_explorer
    build = compile_and_format(
  File "eth_brownie-1.8.2-py3.8.egg/brownie/project/compiler/__init__.py", line 132, in compile_and_format
    output_json = compile_from_input_json(input_json, silent, allow_paths)
  File "eth_brownie-1.8.2-py3.8.egg/brownie/project/compiler/__init__.py", line 247, in compile_from_input_json
    return solidity.compile_from_input_json(input_json, silent, allow_paths)
  File "eth_brownie-1.8.2-py3.8.egg/brownie/project/compiler/solidity.py", line 72, in compile_from_input_json
    raise CompilerError(e)
CompilerError: Compiler returned the following errors:

Pool-flattened.sol:1:1: ParserError: Expected pragma, import directive or contract/interface/library definition.
{{
```

### How can it be fixed?
In `Contract.from_explorer`, check the format of `SourceCode` returned from Etherscan and handle accordingly.


Changed files:
tests/network/contract/test_contract.py, brownie/network/contract.py

diff --git a/brownie/network/contract.py b/brownie/network/contract.py
index 004a0593..86e87259 100644
--- a/brownie/network/contract.py
+++ b/brownie/network/contract.py
@@ -33,8 +33,7 @@ from brownie.exceptions import (
     UndeployedLibrary,
     VirtualMachineError,
 )
-from brownie.project import ethpm
-from brownie.project.compiler import compile_and_format
+from brownie.project import compiler, ethpm
 from brownie.typing import AccountsType, TransactionReceiptType
 from brownie.utils import color
 
@@ -672,32 +671,48 @@ class Contract(_DeployedContractBase):
                 )
             return cls.from_abi(name, address, abi, owner)
 
-        sources = {f"{name}-flattened.sol": data["result"][0]["SourceCode"]}
         optimizer = {
             "enabled": bool(int(data["result"][0]["OptimizationUsed"])),
             "runs": int(data["result"][0]["Runs"]),
         }
-
         evm_version = data["result"][0].get("EVMVersion", "Default")
         if evm_version == "Default":
             evm_version = None
 
-        build = compile_and_format(
-            sources, solc_version=str(version), optimizer=optimizer, evm_version=evm_version
-        )
-        build = build[name]
+        if data["result"][0]["SourceCode"].startswith("{"):
+            # source was verified using compiler standard JSON
+            input_json = json.loads(data["result"][0]["SourceCode"][1:-1])
+            sources = {k: v["content"] for k, v in input_json["sources"].items()}
+            evm_version = input_json["settings"].get("evmVersion", evm_version)
+
+            compiler.set_solc_version(str(version))
+            input_json.update(
+                compiler.generate_input_json(sources, optimizer=optimizer, evm_version=evm_version)
+            )
+            output_json = compiler.compile_from_input_json(input_json)
+            build_json = compiler.generate_build_json(input_json, output_json)
+        else:
+            # source was submitted as a single flattened file
+            sources = {f"{name}-flattened.sol": data["result"][0]["SourceCode"]}
+            build_json = compiler.compile_and_format(
+                sources, solc_version=str(version), optimizer=optimizer, evm_version=evm_version
+            )
+
+        build_json = build_json[name]
         if as_proxy_for is not None:
-            build.update(abi=abi, natspec=implementation_contract._build.get("natspec"))
+            build_json.update(abi=abi, natspec=implementation_contract._build.get("natspec"))
 
-        if not _verify_deployed_code(address, build["deployedBytecode"], build["language"]):
+        if not _verify_deployed_code(
+            address, build_json["deployedBytecode"], build_json["language"]
+        ):
             warnings.warn(
                 f"{address}: Locally compiled and on-chain bytecode do not match!",
                 BrownieCompilerWarning,
             )
-            del build["pcMap"]
+            del build_json["pcMap"]
 
         self = cls.__new__(cls)
-        _ContractBase.__init__(self, None, build, sources)  # type: ignore
+        _ContractBase.__init__(self, None, build_json, sources)  # type: ignore
         _DeployedContractBase.__init__(self, address, owner)
         _add_deployment(self)
         return self
diff --git a/tests/network/contract/test_contract.py b/tests/network/contract/test_contract.py
index 229a2a09..df080b29 100644
--- a/tests/network/contract/test_contract.py
+++ b/tests/network/contract/test_contract.py
@@ -287,9 +287,9 @@ def test_as_proxy_for(network):
     original = Contract.from_explorer("0x3d9819210a31b4961b30ef54be2aed79b9c9cd3b")
     proxy = Contract.from_explorer(
         "0x3d9819210a31b4961b30ef54be2aed79b9c9cd3b",
-        as_proxy_for="0x97BD4Cc841FC999194174cd1803C543247a014fe",
+        as_proxy_for="0x9d0a0443ff4bb04391655b8cd205683d9fa75550",
     )
-    implementation = Contract("0x97BD4Cc841FC999194174cd1803C543247a014fe")
+    implementation = Contract("0x9d0a0443ff4bb04391655b8cd205683d9fa75550")
 
     assert original.abi == proxy.abi
     assert original.address == proxy.address