# Stylus Analyzer
A tool for analyzing Stylus/Rust smart contracts for security issues and bugs.
## Features
- AI-powered contract analysis using OpenAI models
- Static analysis to detect common vulnerabilities
- Unchecked transfer vulnerabilities
- Unsafe panic!() and unwrap() calls
- Unsafe ABI encoding operations
- Locked Ether vulnerabilities
- Extensible detector system for easily adding new vulnerability checks
## Installation
You can install Stylus Analyzer using pip:
```bash
pip install stylus-analyzer
```
For development or the latest features, you can install from the source:
```bash
# Clone the repository
git clone https://github.com/StylusAnalyzer/stylus-analyzer.git
cd stylus-analyzer
# Install the package in development mode
pip install -e .
```
## Usage
### Static Analysis
To perform static analysis on Rust contracts to detect common issues:
```bash
# Analyze a single file
stylus-analyzer static-analyze test_contracts/unsafe_transfer_example.rs
# Analyze all contracts in a directory
stylus-analyzer static-analyze test_contracts/
# Save results to a JSON file
stylus-analyzer static-analyze test_contracts/ -o analysis_results.json
# Save results to a PDF report
stylus-analyzer static-analyze test_contracts/ -p analysis_report.pdf
# Save results in both JSON and PDF formats
stylus-analyzer static-analyze test_contracts/ -o analysis_results.json -p analysis_report.pdf
# Show detailed output including code snippets
stylus-analyzer static-analyze test_contracts/ --verbose
```
The static analyzer will check for various issues including:
- Unchecked transfer return values that can lead to silent failures
- Unsafe panic!() macro calls that cause immediate termination
- Unsafe unwrap() calls that may cause panics
- Unsafe encode_packed operations with dynamic types that may cause hash collisions
- Locked Ether vulnerabilities where funds can be received but not withdrawn
- More detectors can be added by extending the framework
### AI Analysis
To perform AI-powered analysis (requires OpenAI API key):
```bash
# Set your OpenAI API key
export OPENAI_API_KEY=your-api-key
# Analyze a single file
stylus-analyzer analyze-file test_contracts/test_token.rs
# Analyze all contracts in a project directory
stylus-analyzer analyze path/to/project
# Save results to a file
stylus-analyzer analyze path/to/project -o analysis_results.json
```
## Custom Detectors
You can create custom detectors for the static analyzer by following these steps:
1. Create a new detector file in `stylus_analyzer/detectors/`
2. Extend the `BaseDetector` class
3. Implement the required methods
4. Register your detector in the system
Example detector:
```python
from tree_sitter import Node, Tree
from stylus_analyzer.detectors.detector_base import BaseDetector
class MyCustomDetector(BaseDetector):
def __init__(self):
super().__init__(
name="my_custom_detector",
description="Description of what this detector looks for"
)
def detect(self, tree: Tree, code: str, results) -> None:
# Implement your detection logic here
pass
```
You can register your detector in two ways:
1. Add it to the `AVAILABLE_DETECTORS` list in `stylus_analyzer/detectors/__init__.py`:
```python
from stylus_analyzer.detectors.my_custom_detector import MyCustomDetector
AVAILABLE_DETECTORS = [
# Other detectors...
MyCustomDetector
]
```
2. Or register it programmatically:
```python
from stylus_analyzer.detectors import register_detector
from my_package.my_detector import MyCustomDetector
register_detector(MyCustomDetector)
```
## Performance Optimizations
The analyzer includes several performance optimizations:
1. AST generation is done once per file and reused across all detectors
2. Parser initialization uses a singleton pattern to avoid redundant setup
3. Analysis timing is tracked and reported for benchmarking
4. Error handling tracks and reports issues without crashing
## Contributing
Contributions to Stylus Analyzer are welcome! Here's how you can contribute:
### Adding New Vulnerability Detectors
1. Fork the repository
2. Create a new detector file in the `stylus_analyzer/detectors/` directory
3. Implement your detector by extending the `BaseDetector` class
4. Add tests for your detector in the `stylus_analyzer/tests/` directory
5. Submit a pull request with a description of the vulnerability your detector identifies
### Coding Standards
- Use type hints for all function parameters and return values
- Add docstrings for all classes and functions
- Follow PEP 8 style guidelines
- Write unit tests for new functionality
### Development Setup
```bash
# Clone your fork
git clone https://github.com/StylusAnalyzer/stylus-analyzer.git
cd stylus-analyzer
# Create and activate a virtual environment (optional but recommended)
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
# Install in development mode
pip install -e .
# Run tests
pytest
```
## License
This project is licensed under the terms of the MIT license.
## Detectors
### Unchecked Transfer
Detects unchecked transfer calls where the return value is not properly checked. This can lead to silent failures where token transfers fail but the contract continues execution as if they succeeded.
### Unsafe Unwrap
Detects uses of `.unwrap()` in Rust code, which can cause runtime panics if the value is None or Err. In a blockchain context, panics can cause transactions to fail and may lead to loss of funds or unexpected behavior. Instead, developers should use pattern matching, the `?` operator, or other explicit error handling techniques.
### Unsafe Panic
Detects uses of `panic!()` macro in Rust code, which causes immediate termination that cannot be caught or recovered from. In a blockchain context, this will cause the entire transaction to fail with no way to handle the error gracefully. Developers should use Result/Option types with explicit error handling instead.
### Unsafe Encode Packed
Detects potentially unsafe uses of `encode_packed` with dynamic types like strings. When used with dynamic types without delimiters, different inputs can produce the same packed result (e.g., `encode_packed("a", "bc") == encode_packed("ab", "c")`), which can lead to hash collisions. This is particularly problematic when the packed result is used for signatures, authentication, or as a unique identifier. Developers should use regular `encode` which adds padding, use fixed-size types with `encode_packed`, or add delimiters between dynamic values.
### Locked Ether
Detects contracts that can receive Ether but lack withdrawal methods, potentially causing funds to become permanently inaccessible. This occurs when contracts have payable functions or can receive Ether through fallback mechanisms but don't provide any way for users or administrators to retrieve those funds. Developers should implement withdrawal functions with proper access controls, emergency withdrawal mechanisms, or remove the ability to receive Ether if it's not needed for the contract's functionality.
Raw data
{
"_id": null,
"home_page": "https://github.com/StylusAnalyzer/stylus-analyzer",
"name": "stylus-analyzer",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.8",
"maintainer_email": null,
"keywords": "stylus, rust, security, smart-contracts, analysis, ai",
"author": "Jay Sojitra",
"author_email": "jaysojitra@lampros.tech",
"download_url": "https://files.pythonhosted.org/packages/c7/b1/01e851d396ba34752e1835993974756e232eafd0de42df040b66803d05a7/stylus_analyzer-0.1.12.tar.gz",
"platform": null,
"description": "# Stylus Analyzer\r\n\r\nA tool for analyzing Stylus/Rust smart contracts for security issues and bugs.\r\n\r\n## Features\r\n\r\n- AI-powered contract analysis using OpenAI models\r\n- Static analysis to detect common vulnerabilities\r\n - Unchecked transfer vulnerabilities\r\n - Unsafe panic!() and unwrap() calls\r\n - Unsafe ABI encoding operations\r\n - Locked Ether vulnerabilities\r\n - Extensible detector system for easily adding new vulnerability checks\r\n\r\n## Installation\r\n\r\nYou can install Stylus Analyzer using pip:\r\n\r\n```bash\r\npip install stylus-analyzer\r\n```\r\n\r\nFor development or the latest features, you can install from the source:\r\n\r\n```bash\r\n# Clone the repository\r\ngit clone https://github.com/StylusAnalyzer/stylus-analyzer.git\r\ncd stylus-analyzer\r\n\r\n# Install the package in development mode\r\npip install -e .\r\n```\r\n\r\n## Usage\r\n\r\n### Static Analysis\r\n\r\nTo perform static analysis on Rust contracts to detect common issues:\r\n\r\n```bash\r\n# Analyze a single file\r\nstylus-analyzer static-analyze test_contracts/unsafe_transfer_example.rs\r\n\r\n# Analyze all contracts in a directory\r\nstylus-analyzer static-analyze test_contracts/\r\n\r\n# Save results to a JSON file\r\nstylus-analyzer static-analyze test_contracts/ -o analysis_results.json\r\n\r\n# Save results to a PDF report\r\nstylus-analyzer static-analyze test_contracts/ -p analysis_report.pdf\r\n\r\n# Save results in both JSON and PDF formats\r\nstylus-analyzer static-analyze test_contracts/ -o analysis_results.json -p analysis_report.pdf\r\n\r\n# Show detailed output including code snippets\r\nstylus-analyzer static-analyze test_contracts/ --verbose\r\n```\r\n\r\nThe static analyzer will check for various issues including:\r\n- Unchecked transfer return values that can lead to silent failures\r\n- Unsafe panic!() macro calls that cause immediate termination\r\n- Unsafe unwrap() calls that may cause panics\r\n- Unsafe encode_packed operations with dynamic types that may cause hash collisions\r\n- Locked Ether vulnerabilities where funds can be received but not withdrawn\r\n- More detectors can be added by extending the framework\r\n\r\n### AI Analysis\r\n\r\nTo perform AI-powered analysis (requires OpenAI API key):\r\n\r\n```bash\r\n# Set your OpenAI API key\r\nexport OPENAI_API_KEY=your-api-key\r\n\r\n# Analyze a single file\r\nstylus-analyzer analyze-file test_contracts/test_token.rs\r\n\r\n# Analyze all contracts in a project directory\r\nstylus-analyzer analyze path/to/project\r\n\r\n# Save results to a file\r\nstylus-analyzer analyze path/to/project -o analysis_results.json\r\n```\r\n\r\n## Custom Detectors\r\n\r\nYou can create custom detectors for the static analyzer by following these steps:\r\n\r\n1. Create a new detector file in `stylus_analyzer/detectors/`\r\n2. Extend the `BaseDetector` class\r\n3. Implement the required methods\r\n4. Register your detector in the system\r\n\r\nExample detector:\r\n\r\n```python\r\nfrom tree_sitter import Node, Tree\r\nfrom stylus_analyzer.detectors.detector_base import BaseDetector\r\n\r\nclass MyCustomDetector(BaseDetector):\r\n def __init__(self):\r\n super().__init__(\r\n name=\"my_custom_detector\",\r\n description=\"Description of what this detector looks for\"\r\n )\r\n \r\n def detect(self, tree: Tree, code: str, results) -> None:\r\n # Implement your detection logic here\r\n pass\r\n```\r\n\r\nYou can register your detector in two ways:\r\n\r\n1. Add it to the `AVAILABLE_DETECTORS` list in `stylus_analyzer/detectors/__init__.py`:\r\n\r\n```python\r\nfrom stylus_analyzer.detectors.my_custom_detector import MyCustomDetector\r\n\r\nAVAILABLE_DETECTORS = [\r\n # Other detectors...\r\n MyCustomDetector\r\n]\r\n```\r\n\r\n2. Or register it programmatically:\r\n\r\n```python\r\nfrom stylus_analyzer.detectors import register_detector\r\nfrom my_package.my_detector import MyCustomDetector\r\n\r\nregister_detector(MyCustomDetector)\r\n```\r\n\r\n## Performance Optimizations\r\n\r\nThe analyzer includes several performance optimizations:\r\n\r\n1. AST generation is done once per file and reused across all detectors\r\n2. Parser initialization uses a singleton pattern to avoid redundant setup\r\n3. Analysis timing is tracked and reported for benchmarking\r\n4. Error handling tracks and reports issues without crashing\r\n\r\n## Contributing\r\n\r\nContributions to Stylus Analyzer are welcome! Here's how you can contribute:\r\n\r\n### Adding New Vulnerability Detectors\r\n\r\n1. Fork the repository\r\n2. Create a new detector file in the `stylus_analyzer/detectors/` directory\r\n3. Implement your detector by extending the `BaseDetector` class\r\n4. Add tests for your detector in the `stylus_analyzer/tests/` directory\r\n5. Submit a pull request with a description of the vulnerability your detector identifies\r\n\r\n### Coding Standards\r\n\r\n- Use type hints for all function parameters and return values\r\n- Add docstrings for all classes and functions\r\n- Follow PEP 8 style guidelines\r\n- Write unit tests for new functionality\r\n\r\n### Development Setup\r\n\r\n```bash\r\n# Clone your fork\r\ngit clone https://github.com/StylusAnalyzer/stylus-analyzer.git\r\ncd stylus-analyzer\r\n\r\n# Create and activate a virtual environment (optional but recommended)\r\npython -m venv venv\r\nsource venv/bin/activate # On Windows: venv\\Scripts\\activate\r\n\r\n# Install in development mode\r\npip install -e .\r\n\r\n# Run tests\r\npytest\r\n```\r\n\r\n## License\r\n\r\nThis project is licensed under the terms of the MIT license. \r\n\r\n## Detectors\r\n\r\n### Unchecked Transfer\r\nDetects unchecked transfer calls where the return value is not properly checked. This can lead to silent failures where token transfers fail but the contract continues execution as if they succeeded.\r\n\r\n### Unsafe Unwrap\r\nDetects uses of `.unwrap()` in Rust code, which can cause runtime panics if the value is None or Err. In a blockchain context, panics can cause transactions to fail and may lead to loss of funds or unexpected behavior. Instead, developers should use pattern matching, the `?` operator, or other explicit error handling techniques.\r\n\r\n### Unsafe Panic\r\nDetects uses of `panic!()` macro in Rust code, which causes immediate termination that cannot be caught or recovered from. In a blockchain context, this will cause the entire transaction to fail with no way to handle the error gracefully. Developers should use Result/Option types with explicit error handling instead.\r\n\r\n### Unsafe Encode Packed\r\nDetects potentially unsafe uses of `encode_packed` with dynamic types like strings. When used with dynamic types without delimiters, different inputs can produce the same packed result (e.g., `encode_packed(\"a\", \"bc\") == encode_packed(\"ab\", \"c\")`), which can lead to hash collisions. This is particularly problematic when the packed result is used for signatures, authentication, or as a unique identifier. Developers should use regular `encode` which adds padding, use fixed-size types with `encode_packed`, or add delimiters between dynamic values.\r\n\r\n### Locked Ether\r\nDetects contracts that can receive Ether but lack withdrawal methods, potentially causing funds to become permanently inaccessible. This occurs when contracts have payable functions or can receive Ether through fallback mechanisms but don't provide any way for users or administrators to retrieve those funds. Developers should implement withdrawal functions with proper access controls, emergency withdrawal mechanisms, or remove the ability to receive Ether if it's not needed for the contract's functionality.\r\n",
"bugtrack_url": null,
"license": null,
"summary": "AI-powered bug detection tool for Stylus/Rust contracts",
"version": "0.1.12",
"project_urls": {
"Homepage": "https://github.com/StylusAnalyzer/stylus-analyzer"
},
"split_keywords": [
"stylus",
" rust",
" security",
" smart-contracts",
" analysis",
" ai"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "05f117e304e7fdc9bafe2841aaed439b1bad5fdd032c26b562a15f940a741ec0",
"md5": "601b858513d579233c5f5bdbb037bdc4",
"sha256": "f49a359d934c2142bb233bb697e8c16a675d2e5f9b2117ecc2ef4afb4f987c5b"
},
"downloads": -1,
"filename": "stylus_analyzer-0.1.12-py3-none-any.whl",
"has_sig": false,
"md5_digest": "601b858513d579233c5f5bdbb037bdc4",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.8",
"size": 332701,
"upload_time": "2025-07-09T10:47:36",
"upload_time_iso_8601": "2025-07-09T10:47:36.428841Z",
"url": "https://files.pythonhosted.org/packages/05/f1/17e304e7fdc9bafe2841aaed439b1bad5fdd032c26b562a15f940a741ec0/stylus_analyzer-0.1.12-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "c7b101e851d396ba34752e1835993974756e232eafd0de42df040b66803d05a7",
"md5": "1108c4050c4eaf43c492f4473b0176e6",
"sha256": "638ee145467c03cb5d041919d69c8166589716ba798987aaff0d36c7bf0e7d64"
},
"downloads": -1,
"filename": "stylus_analyzer-0.1.12.tar.gz",
"has_sig": false,
"md5_digest": "1108c4050c4eaf43c492f4473b0176e6",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8",
"size": 304723,
"upload_time": "2025-07-09T10:47:38",
"upload_time_iso_8601": "2025-07-09T10:47:38.780565Z",
"url": "https://files.pythonhosted.org/packages/c7/b1/01e851d396ba34752e1835993974756e232eafd0de42df040b66803d05a7/stylus_analyzer-0.1.12.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-07-09 10:47:38",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "StylusAnalyzer",
"github_project": "stylus-analyzer",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "stylus-analyzer"
}