Thank you for your interest in contributing to solsec (Solana Smart Contract Security Toolkit)! This document provides guidelines and instructions for contributing to the project.
- Getting Started
- Development Workflow
- Code Quality Standards
- Testing Requirements
- Pre-commit Setup
- Submission Guidelines
- Security Rule Development
- Documentation
- Rust: Latest stable version (2021 edition)
- Git: For version control
- bun: Package manager (for UI development)
-
Fork the repository on GitHub
-
Clone your fork locally:
git clone https://github.com/YOUR_USERNAME/solsec.git cd solsec -
Add the upstream remote:
git remote add upstream https://github.com/hasip-timurtas/solsec.git
-
Create a new branch for your feature:
git checkout -b feature/your-feature-name
# Build in debug mode
cargo build
# Build in release mode
cargo build --releaseIMPORTANT: Before submitting any changes, you MUST run the full test suite:
# Run the comprehensive test script
./scripts/run-tests.shThis script will:
- β
Check code formatting with
cargo fmt - β
Run linting with
cargo clippy(strict mode) - β
Execute all tests with
cargo test - β Verify release build compilation
# Check formatting
cargo fmt --all -- --check
# Run linting (strict mode - all warnings treated as errors)
cargo clippy --all-targets --all-features -- -D warnings
# Run tests
cargo test --verbose
# Build release
cargo build --release --verboseCRITICAL: This project uses strict clippy mode with -D warnings, meaning ALL clippy warnings are treated as errors.
-
Use
is_some_and()instead ofmap_or(false, |x| condition)// β Bad if path.extension().map_or(false, |ext| ext == "rs") { // β Good if path.extension().is_some_and(|ext| ext == "rs") {
-
Move regex compilation outside loops
// β Bad - creates regex in every iteration for line in lines { if Regex::new(r"pattern").unwrap().is_match(line) { // β Good - compile once, use many times let regex = Regex::new(r"pattern")?; for line in lines { if regex.is_match(line) {
-
Remove unnecessary borrows
// β Bad Command::new("cargo").args(&["test", "arg"]) // β Good Command::new("cargo").args(["test", "arg"])
-
Handle dead code properly
- Don't use
#[allow(dead_code)]as first resort - Actually integrate code into the system
- Only allow dead code for FFI interfaces and public APIs
- Don't use
- Use
cargo fmt --allto format your code - All code must pass
cargo fmt --all -- --check - Follow Rust standard formatting conventions
- Use
anyhow::Resultfor error handling - Avoid
unwrap()in production code - use proper error propagation - Provide clear, actionable error messages
All new features must include:
- Unit Tests: Test individual functions and components
- Integration Tests: Test CLI commands and workflows
- Edge Cases: Test error conditions and boundary cases
#[cfg(test)]
mod tests {
use super::*;
use tempfile::TempDir;
#[test]
fn test_security_rule_detection() {
// Test implementation
}
#[test]
fn test_error_handling() {
// Test error conditions
}
}# Run all tests
cargo test
# Run tests for specific module
cargo test analyzer
# Run tests with output
cargo test -- --nocapturePHILOSOPHY: We use native git hooks, NOT external frameworks.
Why native hooks?
- β Zero dependencies
- β Built into Git
- β Simple shell script
- β Project-specific
- β Easy to debug and modify
-
Create the pre-commit hook (if not already present):
# The hook should already exist, but if not: cp .git/hooks/pre-commit.sample .git/hooks/pre-commit chmod +x .git/hooks/pre-commit -
Verify the hook works:
.git/hooks/pre-commit
The pre-commit hook will:
- Format code with
cargo fmt --all - Run linting with
cargo clippy --all-targets --all-features -- -D warnings - Validate build with
cargo check --all-targets - Auto-add formatted changes to commit
-
Run the full test suite:
./scripts/run-tests.sh
-
Ensure all tests pass:
cargo test -
Check code formatting:
cargo fmt --all -- --check
-
Verify clippy compliance:
cargo clippy --all-targets --all-features -- -D warnings
-
Update your branch:
git fetch upstream git rebase upstream/main
-
Create descriptive commits:
git commit -m "feat: Add new security rule for PDA validation" -
Push your changes:
git push origin feature/your-feature-name
-
Create Pull Request:
- Use a clear, descriptive title
- Include detailed description of changes
- Reference any related issues
- Include testing instructions
Use conventional commit format:
type(scope): description
[optional body]
[optional footer]
Examples:
feat: Add new security rule for integer overflow detectionfix: Resolve false positives in reentrancy detectiondocs: Update README with new CLI optionstest: Add comprehensive tests for analyzer module
-
Create the rule struct:
#[derive(Debug)] pub struct MySecurityRule { // Rule-specific fields }
-
Implement the Rule trait:
impl Rule for MySecurityRule { fn name(&self) -> &str { "my_security_rule" } fn description(&self) -> &str { "Detects my specific vulnerability" } fn check(&self, content: &str, file_path: &Path) -> Result<Vec<RuleResult>> { // Implementation } }
-
Add comprehensive tests:
#[cfg(test)] mod tests { use super::*; #[test] fn test_my_rule_detects_vulnerability() { // Test positive cases } #[test] fn test_my_rule_avoids_false_positives() { // Test negative cases } }
-
Update examples in the
examples/directory with:- Vulnerable code example
- Secure code example
- Clear documentation
- High Accuracy: Minimize false positives
- Clear Messages: Provide actionable feedback
- Proper Severity: Use appropriate severity levels
- Comprehensive Testing: Cover edge cases and variations
- Add rustdoc comments for public APIs
- Include examples in documentation
- Document complex algorithms and security patterns
When adding new features:
- Update feature list
- Add usage examples
- Update command documentation
- Include performance impact notes
- Add both vulnerable and secure examples
- Include clear explanations
- Update the examples README
- Test examples with the tool
If contributing to the UI component:
- bun: Package manager (preferred over npm/yarn)
cd ui
bun install# Start development server
bun dev
# Build for production
bun run build- Use TypeScript for type safety
- Follow Tailwind CSS for styling
- Maintain responsive design
- Test across different screen sizes
- Issues: GitHub Issues
- Discussions: GitHub Discussions
- Discord: Solana Security Community
By contributing to solsec, you agree that your contributions will be licensed under the MIT License.
Thank you for contributing to solsec! Your efforts help make Solana smart contracts more secure for everyone. π‘οΈ