mythx_cli.analyze package

mythx_cli.analyze.command

mythx_cli.analyze.solidity

This module contains functions to generate Solidity-related payloads.

class mythx_cli.analyze.solidity.SolidityJob(target: pathlib.Path)[source]

Bases: mythx_cli.analyze.scribble.ScribbleMixin

generate_payloads(version: Optional[str], solc_path: Optional[str] = None, contract: str = None, remappings: Tuple[str] = None, enable_scribble: bool = False, scribble_path: str = 'scribble')[source]

Generate a MythX analysis request from a given Solidity file.

This function will open the file, try to detect the used solc version from the pragma definition, and automatically compile it. If the given solc version is not installed on the client’s system, it will be automatically downloaded.

From the solc output, the following data is sent to the MythX API for analysis:

  • abi
  • ast
  • bin
  • bin-runtime
  • srcmap
  • srcmap-runtime
Parameters:
  • version – The solc version to use for compilation
  • solc_path – The path to a custom solc executable
  • contract – The contract name(s) to submit
  • remappings – Import remappings to pass to solcx
  • enable_scribble – Enable instrumentation with scribble
  • scribble_path – Optional path to the scribble executable
static patch_solc_bytecode(code: str) → str[source]

Patch solc bytecode placeholders.

This function patches placeholders in solc output. These placeholders are meant to be replaced with deployed library/dependency addresses on deployment, but do not form valid EVM bytecode. To produce a valid payload, placeholders are replaced with the zero-address.

Parameters:code – The bytecode to patch
Returns:The patched bytecode with the zero-address filled in
payload_from_sources(solc_result: Dict, scribble_file: str, solc_version: str) → Dict[source]
set_payload_bytecode_context(payload: Dict, solc_result: Dict)[source]
set_payload_contract_context(payload, contract, solc_result, scribble_file)[source]
static setup_solcx(solc_version: str)[source]
solc_version_from_source(source: str, default_version: str)[source]
solcx_compile(path: str, remappings: Tuple[str], enable_scribble: bool, scribble_file: str = None, solc_path: str = None) → Dict[source]
classmethod walk_solidity_files(solc_version: str, solc_path: Optional[str] = None, base_path: Optional[str] = None, remappings: Tuple[str] = None, enable_scribble: bool = False, scribble_path: str = 'scribble') → List[Dict][source]

Aggregate all Solidity files in the given base path.

Given a base path, this function will recursively walk through the filesystem and aggregate all Solidity files it comes across. The resulting job list will contain all the Solidity payloads (optionally compiled), ready for submission.

Parameters:
  • solc_version – The solc version to use for Solidity compilation
  • solc_path – The path to a custom solc executable
  • base_path – The base path to walk through from
  • remappings – Import remappings to pass to solcx
  • enable_scribble – Enable instrumentation with scribble
  • scribble_path – Optional path to the scribble executable
Returns:

mythx_cli.analyze.truffle

This module contains functions to generate payloads for Truffle projects.

class mythx_cli.analyze.truffle.TruffleJob(target: pathlib.Path)[source]

Bases: mythx_cli.analyze.scribble.ScribbleMixin

A truffle job to be sent to the API.

This object represents a collection of truffle artifacts that will be sent to the API. It aggregates artifacts and transforms them into API-conform payload dicts.

artifact_to_sol_file(artifact_path: str) → str[source]

Resolve an artifact file to its corresponding Solidity file.

This method will take the Truffle artifact’s file name, and recursively search through the current directory and all subdirectories, looking for a Solidity file with the same name.

For additional lookup performance in large Truffle projects with a large dependency graph, the mapping from Solidity file to artifact and vice versa is stored in the job object for future resolution to aboid filesystem interaction.

NOTE: We do not loop up the entries in the mapping here, because we want to avoid accidentally resolving external dependencies defined by path remappings, e.g. @openzeppelin/SafeMath.sol as these don’t turn up as absolute paths in Truffle artifacts but stay in the remapped format.

Parameters:artifact_path – The path to the Truffle artifact
Returns:The corresponding Solidity file path
build_dependency_map() → Dict[Any, Iterable][source]

Build the local dependency mapping.

To speed up lookups when attaching related artifacts to analysis payloads, this method builds a dependency map where the current file is the key, and the value is a set containing all related artifact paths the key file path depends on.

This method is called in the constructor to build the mapping right away and speed up all future lookups.

find_truffle_artifacts() → Union[Tuple[List[str], List[str]], Tuple[None, None]][source]

Look for a Truffle build folder and return all relevant JSON artifacts.

This function will skip the Migrations.json file and return all other files under <project-dir>/build/contracts/. If no files were found, None is returned.

Returns:Files under <project-dir>/build/contracts/ or None
generate_payloads(remappings: Tuple[str] = None, enable_scribble: bool = False, scribble_path: str = 'scribble')[source]

Generate a MythX analysis request payload based on a truffle build artifact.

This will send the following artifact entries to MythX for analysis:

  • contractName
  • bytecode
  • deployedBytecode
  • sourceMap
  • deployedSourceMap
  • sourcePath
  • source
  • ast
  • legacyAST
  • the compiler version
Parameters:
  • remappings – Optional solc import remappings
  • enable_scribble – Whether to instrument the payloads with scribble
  • scribble_path – The path to the scribble executable
Returns:

The payload dictionary to be sent to MythX

get_artifact_context(artifact_file: str) → Dict[str, Any][source]

Get additional context for a given artifact file.

This method will look up the artifacts related to the current one in the instace’s dependency map, load their JSON, and attach source code and AST information to the context object.

To do that, the related Solidity file path is resolved.

Parameters:artifact_file – The artifact file to generate context for
Returns:A dictionary containing source and AST information of all related files
static patch_truffle_bytecode(code: str) → str[source]

Patch Truffle bytecode placeholders.

This function patches placeholders in Truffle artifact files. These placeholders are meant to be replaced with deployed library/dependency addresses on deployment, but do not form valid EVM bytecode. To produce a valid payload, placeholders are replaced with the zero-address.

Parameters:code – The bytecode to patch
Returns:The patched bytecode with the zero-address filled in
sol_file_to_artifact(sol_path: str, artifact_files: Tuple[List[str], List[str]]) → Optional[List[str]][source]

Resolve a Solidity file to the corresponding artifact file.

This method will take the path to a Solidity file and return its corresponding Truffle artifact JSON file. If this relation is already stored in the local artifact mapping, the result will be returned right away. Otherwise, the Solidity path’s file name is retrieved, and looked up in the list of artifact files and add the relation to the job object’s mapping.

Parameters:
  • sol_path – The path of the Solidity file to retrieve the artifact for
  • artifact_files – The list of artifact files in the Truffle build directory
Returns:

The resolved Truffle artifact JSON path

mythx_cli.analyze.util

This module contains helpers for generating MythX analysis payloads.

class mythx_cli.analyze.util.ScenarioMode[source]

Bases: enum.Enum

An enumeration.

SOLIDITY_DIR = 2
SOLIDITY_FILE = 1
TRUFFLE = 3
mythx_cli.analyze.util.delete_absolute_prefix(path: str, prefix: str)[source]

Delete a prefix of an absolute path.

If the path is not absolute yet, it will be expanded.

Parameters:
  • path – Path string to delete the prefix from
  • prefix – Prefix to remove
Returns:

The trimmed path

mythx_cli.analyze.util.detect_truffle_files(path: pathlib.Path, project_base: str = 'build/contracts/*.json') → bool[source]

Detect Truffle projects in paths.

This function detects whether a Truffle project can be found in the given project base path.

Parameters:
  • path – The path prefix to look in (e.g. the CLI target)
  • project_base – The truffle-specific path suffix
Returns:

Boolean indicating whether path contains a truffle project

mythx_cli.analyze.util.determine_analysis_targets(target: str, forced_scenario: str) → List[Tuple[mythx_cli.analyze.util.ScenarioMode, Union[pathlib.Path, str]]][source]

Determine the scenario for an analysis target.

This function will, based on a list of targets or lack thereof, return a list of two-tuples, each containing the determined analysis scenario and the target. In case no initial target is given, the current working directory is used as a replacement.

It is also possible to force evaluation of a given target (or the cwd) by passing the scenario name (“solidity” or “truffle”) to the forced_scenario parameter.

Parameters:
  • target – The initial target to determine the scenario for
  • forced_scenario – A string to manually override scenario detection
Returns:

A list of tuples containing detected scenario and target

mythx_cli.analyze.util.is_valid_job(job) → bool[source]

Detect interface contracts.

This utility function is used to detect interface contracts in solc and Truffle artifacts. This is done by checking whether any bytecode or source maps are to be found in the speficied job. This check is performed after the payload has been assembled to cover Truffle and Solidity analysis jobs.

Parameters:job – The payload to perform the check on
Returns:True if the submitted job is for an interface, False otherwise
mythx_cli.analyze.util.sanitize_paths(job: Dict) → Dict[source]

Remove the common prefix from paths.

This method takes a job payload, iterates through all paths, and removes all their common prefixes. This is an effort to only submit information on a need-to-know basis to MythX. Unless it’s to distinguish between files, the API does not need to know the absolute path of a file. This may even leak user information and should be removed.

If a common prefix cannot be found (e.g. if there is just one element in the source list), the relative path from the current working directory will be returned.

This concerns the following fields: - sources - AST absolute path - legacy AST absolute path - source list - main source

Parameters:job – The payload to sanitize
Returns:The sanitized job