Automatically scan smart contracts on every push or pull request. Fail CI before vulnerabilities reach production.
The easiest way to add security scanning to any GitHub repo. One line in your workflow — no API key needed for the free tier.
name: Smart Contract Security Scan
on:
push:
branches: [ main, master ]
paths: [ '**/*.sol' ]
pull_request:
paths: [ '**/*.sol' ]
jobs:
contractscan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: ContractScan Security Scan
uses: h33min/contractscan-action@v1
with:
fail_on: Critical # Critical | High | Medium | Low
# api_key: ${{ secrets.CONTRACTSCAN_API_KEY }} # optional — Pro/Enterprise
Action source: h33min/contractscan-action.
Scans all .sol files automatically and posts a summary to the PR.
Run security scans directly from your Hardhat project — as a task in your existing workflow.
npm install --save-dev hardhat-contractscan
hardhat.config.jsrequire("hardhat-contractscan");
module.exports = {
contractscan: {
failOn: "Critical", // Critical | High | Medium | Low
// apiKey: process.env.CONTRACTSCAN_API_KEY, // optional — Pro/Enterprise
},
// ... rest of your config
};
npx hardhat contractscan
npm: hardhat-contractscan. Free tier: 1 scan per IP per day. Pro: unlimited.
Scan contracts directly from Claude Code, Cursor, or any MCP-compatible AI editor. Ask your AI assistant to scan a contract and get a security report inline.
pip install contractscan-mcp
~/.claude.json or Cursor settings){
"mcpServers": {
"contractscan": {
"command": "contractscan-mcp",
"env": {
"CONTRACTSCAN_API_KEY": "csk_your_key" // optional — Pro/Enterprise
}
}
}
}
// In Claude Code or Cursor:
"Scan contracts/MyToken.sol for security vulnerabilities"
PyPI: contractscan-mcp. Uses Anthropic MCP protocol to expose ContractScan as a tool in your AI editor.
Scan Solidity contracts directly inside VS Code. Inline diagnostics highlight vulnerabilities at the source line. No terminal required.
⚠️ Marketplace listing coming soon. Install manually via .vsix while we complete the review process.
Download contractscan-0.1.0.vsix by emailing contractscan.raccoonworld@gmail.com, then run:
code --install-extension contractscan-0.1.0.vsix
Open a .sol file → Command Palette → ContractScan: Scan Current File
Or set contractscan.autoScan: true to scan on save.
Works without an API key (free tier). Add contractscan.apiKey in settings for Pro/Enterprise.
Use the /ci/scan endpoint to integrate ContractScan into any CI system
— GitHub Actions, GitLab CI, CircleCI, Jenkins, or any pipeline that can run curl.
Free tier: 1 scan per IP per day (no API key needed).
Note: this limit applies to CI/CD API scans only — QuickScan (web UI) has a separate free tier.
For unlimited CI scans, get a Pro subscription and generate an API key.
From your dashboard, activate your license key, then create an API key:
curl -X POST https://contract-scanner.raccoonworld.xyz/api/keys \
-H "Content-Type: application/json" \
-d '{"name":"CI Pipeline","license_key":"YOUR_LICENSE_KEY"}'
Store the key as a secret in your CI system (e.g. CONTRACTSCAN_API_KEY).
# No API key needed for free tier (1 scan per IP per day)
curl -X POST https://contract-scanner.raccoonworld.xyz/ci/scan \
-H "X-Fail-On: Critical" \
-F "file=@contracts/MyToken.sol"
# Paid tier with API key
curl -X POST https://contract-scanner.raccoonworld.xyz/ci/scan \
-H "X-Api-Key: csk_your_key" \
-H "X-Fail-On: Critical" \
-F "file=@contracts/MyToken.sol"
# Response:
# {
# "success": true,
# "contract_name": "MyToken",
# "findings_count": 2,
# "severity_summary": {"High": 1, "Low": 1},
# "passed": true,
# "fail_reason": null,
# ...
# }
Set X-Fail-On to control when CI fails:
| X-Fail-On value | Fails when findings include… |
|---|---|
Critical (default) |
Any Critical finding |
High |
Any Critical or High finding |
Medium |
Any finding ≥ Medium |
Low |
Any finding at all |
For CI systems without a native action, use curl directly.
This also works in GitHub Actions as an alternative to the uses: syntax above.
name: Smart Contract Security Scan
on:
push:
branches: [ main, master ]
paths: [ '**/*.sol' ]
pull_request:
paths: [ '**/*.sol' ]
jobs:
contractscan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Scan contracts
run: |
EXIT_CODE=0
for sol in $(find . -name '*.sol' -not -path '*/node_modules/*'); do
echo "Scanning $sol ..."
HTTP_CODE=$(curl -s -o /tmp/cs_result.json -w '%{http_code}' \
-X POST https://contract-scanner.raccoonworld.xyz/ci/scan \
-H "X-Fail-On: Critical" \
-H "X-Api-Key: ${{ secrets.CONTRACTSCAN_API_KEY }}" \
-F "file=@$sol")
cat /tmp/cs_result.json
PASSED=$(python3 -c "import json; print(json.load(open('/tmp/cs_result.json')).get('passed', True))")
if [ "$PASSED" = "False" ]; then EXIT_CODE=1; fi
done
exit $EXIT_CODE
Free tier: omit the X-Api-Key header — 1 scan per IP per day, no key needed.
Pro and Enterprise subscribers can register webhook URLs to receive scan results in real time (Slack, Discord, custom dashboards). Requires an API key.
curl -X POST https://contract-scanner.raccoonworld.xyz/api/webhooks \
-H "Content-Type: application/json" \
-d '{
"api_key_id": "your_key_id",
"url": "https://hooks.slack.com/services/...",
"events": "scan.complete",
"secret": "optional_hmac_secret"
}'
Webhook payloads are signed with HMAC-SHA256 when a secret is provided
(X-ContractScan-Signature: sha256=...).