Code Inspector
Code Inspector seamlessly integrates with Github to maximize security with every step of your development process via automatic code analysis powered by machine learning intelligence and state-of-the-art tools developed by our security experts.
For every push to your code, the OpenZeppelin Code Inspector dives into a detailed examination, identifying potential vulnerabilities and suggesting improvements to enhance your code quality. It generates a succinct report, summarizable in your PR comments for quick and immediate access, while a more detailed report is made available on Defender.
Use cases
-
Automatically conduct security analysis on pull requests, identifying vulnerabilities and suggesting improvements.
-
Utilize summarized reports in the pull request for immediate insights into your code’s health and security.
-
Access comprehensive, detailed reports on Defender for an in-depth understanding of potential vulnerabilities and code optimization areas.
-
Use OpenZeppelin’s Dependency Checker to identify reused contracts and match them against a database of known vulnerabilities.
-
Apply static analysis rules to Solidity files, identifying potential issues and their severity for high-quality code maintenance.
Features
Some issues found by Code Inspector are detected by our AI models. Keep in mind that while we provide confidence levels, the models may occasionally generate incorrect or misleading information. Make sure to verify the information accordingly and we’d love to hear your feedback. |
Code Inspector has a wide range of functionalities designed to enhance security, efficiency, and code quality. These processes are powered by machine learning models and state-of-the-art tools developed by our security experts.
-
Reused Code: Identifies vulnerabilities in reused smart contract code by generating a unique fingerprint for each contract and matching it against a database of known issues.
-
Vulnerable Dependencies: Notify when a OpenZeppelin Contracts dependency with a known vulnerability is used, providing you with the necessary information to address the issue.
-
Test Suggestions: Opportunities to apply fuzzing tests to functions, providing you with areas where further testing could prove beneficial.
-
External Call Safety: Safety of external calls, highlighting any instances that might pose a severity concern.
-
Standard Compatibility: Compatibility of your contracts with established standards, flagging potential compatibility issues.
-
Reentrancy Attack Vectors: Potential reentrancy attack vectors at both the file and function level, assigning these threats high-severity labels.
-
Code Readability: Missing docstrings in functions and misspelled words throughout the codebase, ensuring your code is as legible and understandable as possible.
-
Code Efficiency and Security Practices: Areas in your code where improvements can be made for better performance and highlights potential security risks, enabling you to optimize and secure your contracts more effectively.
Installation
Installation must be initiated from Defender. Installing the app directly from GitHub will not correctly set up the integration. |
The installation process connects your Defender account and your GitHub repositories. Follow the following steps:
-
Navigate to the Code Inspector page on Defender.
-
Click on the Install Code Inspector button, which redirects you to Github.
-
Select and approve the repositories to install the app.
-
Generate your first report by creating or updating a pull request on a repository that has the app installed.
The installation is currently done solely through Defender, ensuring a seamless connection for the reports. Following the installation, no additional setup is required. If you encounter installation issues, refer to our Troubleshooting section for guidance.
Usage
Code Inspector is designed to streamline your code analysis workflow. Once installed, the app is triggered whenever a pull request (PR) is opened or a new commit is pushed to an existing PR in your GitHub repository. To avoid skipping the report, the PR must contain at least a modification to any Solidity file or the package.json
file.
The app automatically generates a summary report for each new commit, which is posted as a comment in your PR. This summary report is continuously updated with the latest issues discovered in the most recent commit, and the commit hash is directly viewable in the report.
Along with the summary reports in PR comments, a detailed report for each commit is created and can be accessed on Defender, offering in-depth information on the identified issues and how to fix them.
If you wish to stop receiving reports for a specific repository, it’s as simple as navigating to the Code Inspector settings and removing the respective repository from the list.
Statuses
These are the possible statuses of reports:
-
Running
: The report has been triggered, and it’s running. -
Succeeded
: The report has been successfully generated, and it’s available in Defender and Github. -
Failed
: The report has failed. Make sure that your repository contains valid Solidity files. If this issue persists, please get in touch. -
Throttled
: The report has been throttled as your tenant exceeded the Code Inpsector quota limit. If you would like to increase your quota, please get in touch. -
Skipped
: The report has been skipped. Check that the PR and/or commit contains at least one modification to a Solidity file or thepackage.json
file.
Reports
Summary Report
The summary report provides a clear overview of potential vulnerabilities detected in the code during the review process. The report is conveniently categorized by process and severity level, making it easier to identify areas that need attention. You can navigate to the complete report on Defender via the provided link. Each report is tied to a specific commit, ensuring accurate tracking of changes and issues over time.
In this example, you can see the number of issues detected by Code Inspector, along with their respective severity levels. By clicking the link at the bottom of the report, you can view the full details of these vulnerabilities on Defender.
Issues
Full reports identify issues within your smart contracts using a broad range of rules. The rules cover many aspects, such as known vulnerabilities, best practices, code efficiency, and secure coding principles.
Each issue is assigned a severity level based on the potential impact on the contract’s functionality and security. An explanation accompanies each flagged issue, articulating the reason for the concern.
Every issue has a suggested resolution tailored to improving your code quality and overall security. This might include recommendations to refine your code, modify visibility scopes, apply necessary mathematical checks, enhance documentation, or adhere to a specific Ethereum standard.
Depicted below is an example of a vulnerability detected in a dependency with a brief description of its potential impact. The specific dependency and its version are outlined, pinpointing where the problem exists.
To help you resolve these issues, recommendations on updates or patches that can address the vulnerabilities are provided along with the relevant advisory links for a more detailed understanding of the issue.
By reviewing and applying the proposed solutions in this report, you can enhance the robustness and reliability of your smart contracts, ensuring adherence to best practices and industry standards. This makes the audit process smoother and improves the preparedness of your contracts for successful deployment.
Standards
This feature introduces a new section in the report called Standards. This section provides insights into your contracts that implement interfaces from the OpenZeppelin Contracts library. For example, if you are using an IERC20
, Code Inspector will check the implementation details and properties to ensure you are using this ERC correctly.
Detailed Checks
For each function and event defined in an interface, Code Inspector performs comprehensive checks to verify compliance with the standard. These checks include:
-
Signature: Ensures that the function or event signature matches the standard’s specification. Example:
transfer(address,uint256)
-
Visibility: Checks that the visibility of functions and events adheres to the standard’s requirements. Example:
external
,public
-
Mutability: For functions, ensures that the mutability is correctly specified as per the standard. Example:
view
,pure
-
Return Type: Verifies that the return types of functions align with the expected types defined in the standard. Example
returns (bool)
-
Parameter Names: Confirms that the parameter names are consistent with those defined in the standard, enhancing code readability and maintainability. Example:
transfer(address recipient, uint256 amount)
-
Return Names: Ensures that the return variable names, where used, are consistent with the standard. Example:
returns (bool success)
If any attribute of a function or event fails, the entire function or event is marked as failed. Additionally, if any function or event within an implementation fails, the entire implementation is considered non-compliant.
Configuration
You can configure repository-specific parameters for Code Inspector using a file called defender.config.json
in the root directory. The structure of the file is separated into processes run by Code Inspector. Each process has a list of parameters that you can adjust to your needs. For example, you can specify which directories to scan, which is useful to prevent Code Inspector from analyzing test or script files written in Solidity.
Contract Inspector
Contract Inspector runs a set of rules to detect potential issues in your code. You can configure the following parameters:
-
enabled
: ability to turn off the Contract Inspector. False meaning not to run, and true to run. (default:true
) -
scan_directories
: list of directories to scan with paths starting from the root directory. default:["."]
-
include_rules
: list of rules to run. default: all rules. -
exclude_rules
: list of rules to not run. default: none.
Dependency Checker
Dependency Checker verifies that your dependencies are not vulnerable to known issues. You can configure the following parameters:
-
enabled
: ability to turn off Dependency Checker. False meaning not to run, and true to run. (default:true
)
Example
The following defender.config.json
configuration file will disable Dependency Checker and run Contract Inspector on the src/contracts1
and src/contracts2
directories, excluding two rules (naming-convention
and unused-state
).
{
"contract_inspector": {
"enabled": true,
"scan_directories": ["src/contracts1", "src/contracts2"],
"exclude_rules": ["naming-convention", "unusued-state"]
},
"dependency_checker": {
"enabled": false
}
}
Assets
The Assets page allows you to manage your Code Inspector assets, supporting two types: Smart Contracts and GitHub repositories. When you install the Code Inspector GitHub app and select repositories, they will appear on this page. Additionally, you can create Smart Contract assets from addresses in your address book. Note that Smart Contract assets must be verified on Etherscan for this feature to work.
Smart Contract assets can be manually triggered for reports on the report page. GitHub assets can be triggered manually and automatically from new pull requests (PRs) and commits.
Settings
The Asset Settings page offers two main settings to manage how Defender handles asset security: Automatically Generate Report and Vulnerability Detection.
Automatically Trigger Report for Pull Requests
Automatically Generate Report, is specifically for GitHub repositories. When enabled, this setting ensures continuous monitoring by generating new reports automatically whenever a new pull request (PR) is opened or a new commit is pushed to a PR.
Active Vulnerability Detection and Notification
Active Vulnerability Detection and Notification provides a robust security measure by automatically scanning your assets for new vulnerabilities. This setting is applicable to both GitHub repositories and smart contracts. To enable this feature for Github repositories assets, you must activate the setting and select a specific branch to be monitored.
-
Automated Scanning: Leveraging Defender’s advanced smart contracts scanning capabilities, when our team becomes aware of a new vulnerability, whether disclosed or undisclosed, we promptly update our scanning algorithms to detect it. We then scan all assets configured to be monitored
-
Automated Notification: Once the automatic scanning is completed an automated system notification email will be sent to inform you whether the vulnerability was detected in your monitored assets. If detected, the notifications include relevant information tailored to the nature of the vulnerability.
-
Risk Mitigation: When detected, to aid in addressing and mitigating detected vulnerabilities, notifications may include suggestions for risk mitigation, providing actionable steps for administrators to protect their smart contracts and associated assets.
By enabling Active Vulnerability Detection and Notification for your assets, you can benefit from continuous, automated scanning and timely notifications, empowering you to respond quickly to new threats and maintain the security of your smart contracts and GitHub repositories. This proactive approach ensures that you can stay ahead of potential vulnerabilities and safeguard your code effectively.
Settings
The Settings page allows you to manage the permissions and access level of the Code Inspector. If you need to make changes to the repositories that the app has access to, a convenient link takes you directly to the GitHub settings page of the app, facilitating effortless repository management.
In the Github tab, you can globally suspend or uninstall the app, giving you complete control over its operation within your projects.
Troubleshooting
Installation Issues
-
Installing the app outside Defender: Code Inspector must be installed via Defender. If you attempt to install it from elsewhere, the installation will not succeed. Ensure you’re logged in to your OpenZeppelin account and navigate to Code Inspector from Defender for a successful installation.
-
Code Inspector Access: Access to Code Inspector is required for a successful installation. If you find that you don’t have access and you think this is a mistake, contact OpenZeppelin support to get the necessary permissions.
Repository Size Issues
Errors related to analysis timeouts are often caused by large codebases. To mitigate this issue, it is recommended to use the scan_directories
option in the defender configuration file to scope the analysis to relevant files only. By specifying which directories to include in the scan, the configuration file can significantly reduce processing times and prevent timeouts. For detailed instructions on setting up the configuration file, please refer to the Configuration section.
Rules
ID | Description | Severity |
---|---|---|
|
Identifies any instance of a Uniswap Router V2 addLiquidity call. |
note |
|
Identifies when the length of an array can be written to the stack to save gas. |
note |
|
Identifies a potentially unsafe external call. |
medium |
|
Identifies usage of chainlink’s deprecated functions. |
medium |
|
Identifies usage of |
note |
|
Identifies a possible violation of the check, effect and interact pattern. |
ethtrust |
|
Identifies if the contract may not be compatible with ERC-4337. |
note |
|
Identifies when the external call return data check is missing. |
note |
|
Identifies when a constant is not using the proper format. |
note |
|
Identifies the use of strict equalities that can cause a Gridlock. |
medium |
|
Identifies an instance of a variable initialized to its default value. |
note |
|
Identifies when an there is a delegatecall or call code to an arbitrary address. |
high |
|
Identifies an instance of delegatecall. |
ethtrust |
|
Identifies whether different Solidity versions are used. |
low |
|
Identifies if |
note |
|
Identifies a possible docstrings and code mismatch. |
low |
|
Identifies duplicated imports. |
note |
|
Identifies whether a balance is compared to an exact value. |
ethtrust |
|
Identifies external calls as a possible vector for a reentrancy attacks. |
note |
|
Identifies if there are fallback functions with return values. |
note |
|
Identifies pragma directives that do not specify a particular, fixed version of Solidity. |
low |
|
Identifies when a state variable is initialized by a function. |
note |
|
Identifies a possible access control attack vector on a function. |
high |
|
Identifies a possible reentrancy attack vector on a function. |
high |
|
Identifies if function visibility is unnecessarily broad. |
note |
|
Identifies when an external call has a hard-coded gas limit. |
low |
|
Identifies a hashing of a packed encoded dynamic value. |
ethtrust |
|
Identifies a hardhat console import. |
note |
|
Identifies todo comments in the code. |
note |
|
Identifies when a contract has a inconsistent order. |
note |
|
Identifies inconsistent usage of named returns within a codebase. |
note |
|
Identifies when a contract includes the |
note |
|
Identifies an incorrect definition of a modifier. |
medium |
|
Identifies the use of |
note |
|
Identifies when a file has multiple SPDX licenses. |
note |
|
Identifies when additive inverse of an int variable is evaluated. |
note |
|
Identifies when an upgradeable contract does not have a gap variable. |
low |
|
Identifies when a lack of indexed event parameter. |
note |
|
Identifies when a contract does not have a security contact. |
note |
|
Identifies when a lack of SPDX license identifier. |
note |
|
Identifies any instance of locked ETH within a contract. |
high |
|
Identifies when some code may be vulnerable to a Solidity compiler vulnerability. |
medium |
|
Identifies when a function is missing docstrings. |
low |
|
Identifies when a function is missing the initializer modifier. |
low |
|
identifies when a mapping is missing named parameters |
note |
|
Identifies when a function is missing the return statement. |
low |
|
Detects the misuse of a Boolean literal (used in complex expressions or as conditionals). |
medium |
|
Identifies usage of msg.value inside a loop. |
note |
|
Identifies multiple contract declarations per file. |
note |
|
Identifies in a codebase when two or more contracts have the same name. |
note |
|
Identifies a non-explicit import. |
note |
|
Identifies usage of the |
note |
|
Identifies a Solidity file with an outdated Solidity version. |
note |
|
Identifies cases where state variables are explicitly set to values within a contract but are overwritten by the constructor. |
note |
|
Identifies the potential for incorrect ABI decoding. |
note |
|
Identifies a possible vector for a return bomb attack. |
note |
|
Identifies a Solidity file with pragma that spans versions of solidity where breaking changes may have been introduced. |
low |
|
Identifies possible precision loss due to division before multiplication |
note |
|
Identifies a redundant use of SafeMath library. |
note |
|
Identifies when a revert string could be replaced by a custom error. |
note |
|
Identifies when a require statement does not check for any conditions. |
low |
|
Identifies when an error message is missing from the require statement. |
low |
|
Identifies a require statement with multiple conditions. |
low |
|
Identifies when a revert statement is missing the error message. |
low |
|
Identifies an instance of selfdestruct. |
ethtrust |
|
Identifies if a function is updating the state without an event emission. |
note |
|
Identifies when the visibility of a state variable that has not been explicitly declared. |
note |
|
Identifies possible attacks on sushiswap callback where a fake pool address can pass authorization check. |
note |
|
Identifies when the arguments of function call have been swapped. |
note |
|
Identifies a literal number with many digits. |
note |
|
Identifies usage of |
high |
|
Identifies when the external call fail check is missing. |
ethtrust |
|
Identifies that an incremental update is not wrapped in an unchecked block. |
note |
|
Identifies unchecked code inside a function. |
note |
|
Identifies a potentially unsafe usage of unchecked math. |
high |
|
Identifies the use of unicode direction control character. |
ethtrust |
|
Identifies an unnecessary assignment of a variable. |
note |
|
Identifies an unnecessary cast. |
note |
|
Identifies any use of unsafe ABI encoding. |
low |
|
Identifies if a |
note |
|
Identifies an unused function argument. |
note |
|
Identifies an unused enum. |
note |
|
Identifies an unused error. |
note |
|
Identifies an unused event. |
note |
|
Identifies an unused function with internal or private visibility. |
note |
|
Identifies an unused import. |
note |
|
Identifies an unused named return variable. |
note |
|
Identifies an unused state variable. |
note |
|
Identifies an unused struct. |
note |
|
Identifies instance of transfer or send. |
low |
|
Identifies if an |
note |
|
Identifies variables that could be declared as |
note |
|
Identifies variables that are only ever set in the constructor and could be |
note |
|
Identifies the call to a constructor that is not implemented. |
low |