CLI tool for auditing Foundry deployment scripts for security vulnerabilities
Project description
DeployGuard
DeployGuard is a CLI tool for auditing Foundry deployment scripts for security vulnerabilities, best practice violations, and missing test coverage. It focuses on detecting CPIMP (Clandestine Proxy In the Middle of Proxy) vulnerabilities and other security anti-patterns.
⚠️ Important Notes
DeployGuard is an opinionated tool based on security experience and best practices. The rules, recommendations, and best practices enforced by DeployGuard reflect real-world security lessons learned from auditing smart contract deployments. While these opinions are grounded in practical security experience, teams may have different approaches that are equally valid for their specific use cases.
DeployGuard is NOT a security guarantee. This tool helps development teams follow best practices and established guidelines for smart contract deployments. It is designed to catch common anti-patterns and provide actionable recommendations, but:
- Does not replace professional security audits
- Does not guarantee the absence of vulnerabilities
- May produce false positives or miss certain issues
- Should be used as one layer of a comprehensive security strategy
Installation
From PyPI
pip install deployguard
From Source
git clone https://github.com/0xstormblessed/deployguard.git
cd deployguard
pip install -e .
Requirements
- Python 3.10+
- Foundry (for Solidity compilation)
Quick Start
# Audit all deployment scripts in a directory
deployguard audit ./script
# Audit a single deployment script
deployguard audit script/Deploy.s.sol
# Verify a deployed proxy on-chain
deployguard verify 0x1234...5678 \
--rpc https://eth-mainnet.g.alchemy.com/v2/YOUR_KEY \
--expected 0xABCD...EF01
# Check test coverage for deployment scripts
deployguard check
# List all available rules
deployguard rules
Commands
audit - Static Analysis
Analyze deployment scripts for security vulnerabilities.
# Audit a directory (recursive)
deployguard audit ./script
# Audit with JSON output (for CI/CD)
deployguard audit ./script -o json
# Filter files with glob patterns
deployguard audit . --include '**/*.s.sol' --exclude '**/mock/**'
# Stop on first error
deployguard audit ./script --fail-fast
Options:
| Option | Description |
|---|---|
-o, --output |
Output format: console, json, sarif |
--include |
Glob patterns to include |
--exclude |
Glob patterns to exclude |
--no-gitignore |
Don't respect .gitignore patterns |
--fail-fast |
Stop on first analysis error |
Exit Codes:
0- No critical/high findings1- Critical or high severity findings detected
verify - Dynamic Analysis
Verify a deployed proxy matches the expected implementation address.
deployguard verify 0xProxyAddress \
--rpc https://eth-mainnet.g.alchemy.com/v2/KEY \
--expected 0xExpectedImpl \
--admin 0xExpectedAdmin
Example: Detecting the USPD CPIMP Attack
This example verifies the USPD proxy on Ethereum mainnet. The proxy was exploited via a CPIMP attack where an attacker front-ran the initialization:
# Requires an Ethereum mainnet RPC endpoint
deployguard verify 0x1346B4d6867a382B02b19A8D131D9b96b18585f2 \
--rpc https://eth-mainnet.g.alchemy.com/v2/YOUR_KEY \
--expected 0x93486b98e64de344d6a5a322a4bd80e65d83e5ca
This will detect IMPL_MISMATCH because the on-chain implementation differs from the intended cUSPDToken implementation - evidence of the CPIMP attack.
Options:
| Option | Description |
|---|---|
--rpc |
RPC endpoint URL (required) |
--expected |
Expected implementation address (required) |
--admin |
Expected admin address (optional) |
-o, --output |
Output format: console, json |
check - Test Coverage
Check that deployment scripts have corresponding test coverage.
# Check current directory
deployguard check
# Check specific project
deployguard check ./my-project
# JSON output
deployguard check -o json
rules - List Rules
List all available security rules.
# List all rules
deployguard rules
# Filter by category
deployguard rules --category proxy
# Filter by severity
deployguard rules --severity critical
# JSON output
deployguard rules -o json
Rule Categories
Proxy Rules (CPIMP Detection)
| Rule | Severity | Description |
|---|---|---|
NON_ATOMIC_INIT |
Critical | Non-atomic proxy initialization allows front-running |
HARDCODED_IMPL |
Medium | Hardcoded implementation address |
MISSING_IMPL_VALIDATION |
Medium | Missing implementation address validation |
Security Rules
| Rule | Severity | Description |
|---|---|---|
PRIVATE_KEY_ENV |
High | Private key loaded from environment variable |
MISSING_OWNERSHIP_TRANSFER |
Medium | Ownership not transferred after deployment |
DEPLOYER_ADMIN |
Medium | Deployer retains admin privileges |
UUPS_NO_AUTHORIZE |
Critical | UUPS missing _authorizeUpgrade override |
UUPS_NO_DISABLE_INIT |
High | UUPS missing _disableInitializers |
UUPS_UPGRADE_OVERRIDE |
Medium | UUPS override of upgradeToAndCall |
UUPS_UNSAFE_OPCODE |
High | UUPS uses delegatecall/selfdestruct |
Testing Rules
| Rule | Severity | Description |
|---|---|---|
NO_TEST |
Medium | Deployment script has no test coverage |
TEST_NO_RUN |
Low | Test doesn't call run() function |
Dynamic Rules (On-Chain Verification)
| Rule | Severity | Description |
|---|---|---|
IMPL_MISMATCH |
Critical | On-chain implementation doesn't match expected |
UNINITIALIZED_PROXY |
Critical | Proxy is not initialized |
ADMIN_MISMATCH |
High | Admin slot doesn't match expected |
NON_STANDARD_PROXY |
Medium | Non-standard proxy pattern detected |
DELEGATECALL_IMPL |
Info | Implementation contains DELEGATECALL (expected for UUPS) |
CI/CD Integration
GitHub Actions
name: DeployGuard Audit
on: [push, pull_request]
jobs:
audit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Foundry
uses: foundry-rs/foundry-toolchain@v1
- name: Install DeployGuard
run: pip install deployguard
- name: Run Audit
run: deployguard audit ./script -o json > audit-report.json
- name: Upload Report
uses: actions/upload-artifact@v4
with:
name: audit-report
path: audit-report.json
Exit Code Usage
# In CI scripts, check exit code
deployguard audit ./script
if [ $? -ne 0 ]; then
echo "Security issues found!"
exit 1
fi
Example Output
================================================================================
DEPLOYGUARD ANALYSIS REPORT
================================================================================
================================================================================
FILE: script/Deploy.s.sol
================================================================================
[CRITICAL] NON_ATOMIC_INIT: Non-Atomic Proxy Initialization
Location: line 45 in Deploy.s.sol
→ ERC1967Proxy proxy = new ERC1967Proxy(address(impl), "");
Description: ERC1967Proxy deployed with empty initialization data...
Warning Why this matters:
This is vulnerable to a CPIMP (Clandestine Proxy In the Middle of Proxy) attack.
Attackers monitor mempools for proxy deployments with empty init data, then
front-run the initialization transaction to gain admin control. Dedaub identified
CPIMP as affecting thousands of contracts across multiple chains.
Related Exploits:
- https://rekt.news/uspd-rekt/
Documentation:
- https://dedaub.com/blog/the-cpimp-attack-an-insanely-far-reaching-vulnerability-successfully-mitigated/
Recommendation: Pass initialization data to the proxy constructor...
================================================================================
SUMMARY
================================================================================
Files scanned: 5
Files with findings: 1
Total findings: 1 (1 critical, 0 high, 0 medium, 0 low, 0 info)
Status: FAILED
================================================================================
Contributing
Contributions are welcome! See CONTRIBUTING.md for development setup, code style, and PR guidelines.
License
DeployGuard is licensed under the Apache License 2.0.
- Free for all use - personal, commercial, and open source projects
- Commercial license required - if offering DeployGuard as a SaaS or managed service
For commercial licensing inquiries, contact the project maintainers. See LICENSE for full text.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file deployguard-0.1.2.tar.gz.
File metadata
- Download URL: deployguard-0.1.2.tar.gz
- Upload date:
- Size: 96.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b7bccadcf7a886391c3c89d81ce0d615808538adcc839cb1bba16b6efb091e2f
|
|
| MD5 |
cb5e2e6edb0d06111b667e4a51ceed56
|
|
| BLAKE2b-256 |
323295bc0215f7c524cd5c6fb14083495c74cc7a2609d43fc5268254d26dca0a
|
File details
Details for the file deployguard-0.1.2-py3-none-any.whl.
File metadata
- Download URL: deployguard-0.1.2-py3-none-any.whl
- Upload date:
- Size: 99.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
579fdb6fd3cb980c7049b60fe2562910b1cbfdca218053c25e15c2d91f9d4181
|
|
| MD5 |
9a617c4bfc497a08f04635c4e1a34ec6
|
|
| BLAKE2b-256 |
bd0bc033717b36c00afe1652efc98f71b21fd50a635fb2fa323b965e5a6cb904
|