Multi Language Projects
Scanning projects with multiple smart contract languages. Modern blockchain projects often use multiple languages: - Solidity for main contracts - Vyper for...
Multi-Language Projects
Scanning projects with multiple smart contract languages.
Overview
Modern blockchain projects often use multiple languages:
- Solidity for main contracts
- Vyper for specialized components
- Rust for cross-chain bridges
- Move/Cairo for L2 deployments
BlockSecOps handles multi-language projects automatically.
Automatic Detection
When you upload a project, BlockSecOps:
- Scans all files in the archive
- Identifies languages by extension and pragmas
- Applies appropriate scanners per language
- Generates unified reports across all languages
Detection Methods
| Method | Example |
|---|---|
| File extension | .sol, .vy, .rs |
| Pragma statement | pragma solidity ^0.8.0; |
| Version comment | # @version 0.3.9 |
| Config file | Cargo.toml, foundry.toml |
Project Structure
Typical Multi-Language Project
project/
├── contracts/ # Solidity
│ ├── Token.sol
│ ├── Bridge.sol
│ └── interfaces/
├── vyper/ # Vyper
│ ├── Vault.vy
│ └── Oracle.vy
├── programs/ # Solana/Rust
│ └── bridge/
│ ├── src/
│ │ └── lib.rs
│ └── Cargo.toml
├── foundry.toml
└── package.json
What Gets Scanned
| Directory | Language | Scanners Applied |
|---|---|---|
contracts/ |
Solidity | Slither, Solhint, Aderyn, etc. |
vyper/ |
Vyper | Vyper Analyzer, Moccasin |
programs/ |
Rust | Cargo Audit, Clippy, Soteria |
Scanner Selection
Automatic Selection
BlockSecOps automatically selects scanners per language:
Standard Preset:
- Solidity → Slither + Solhint + Aderyn + Semgrep + Wake
- Vyper → Vyper Analyzer + Moccasin
- Rust → Cargo Audit + Clippy + Soteria + X-ray
Manual Override
You can specify scanners per language in advanced settings:
{
"scanners": {
"solidity": ["slither", "mythril"],
"vyper": ["vyper-analyzer"],
"rust": ["cargo-audit", "soteria"]
}
}
Cross-Language Vulnerabilities
Some vulnerabilities span languages:
Interface Mismatches
Solidity interface doesn't match Vyper implementation:
// Solidity interface
interface IVault {
function deposit(uint256 amount) external returns (bool);
}
# Vyper implementation - different return type!
@external
def deposit(amount: uint256): # Returns nothing
...
Detection: BlockSecOps flags interface mismatches across languages.
Cross-Chain Bridge Issues
Solidity contract calls Rust program:
// Solidity side
function bridgeToSolana(bytes32 recipient, uint256 amount) external {
// Emits event for Solana program
}
// Rust side must validate correctly
pub fn process_bridge_in(
accounts: &[AccountInfo],
data: BridgeData,
) -> ProgramResult {
// Must validate sender chain proof
}
Detection: Scanners check both sides for validation gaps.
Unified Reporting
Combined Dashboard
All findings appear in one dashboard:
- Filter by language
- Sort by severity across languages
- Track remediation per component
Report Sections
=== Security Scan Report ===
SOLIDITY (5 contracts)
├── Critical: 0
├── High: 2
├── Medium: 8
└── Low: 5
VYPER (2 contracts)
├── Critical: 0
├── High: 0
├── Medium: 2
└── Low: 1
RUST/SOLANA (1 program)
├── Critical: 0
├── High: 1
├── Medium: 3
└── Low: 2
TOTAL: 24 findings
Configuration
Project Configuration
Create a blocksecops.json in your project root:
{
"languages": {
"solidity": {
"paths": ["contracts/", "src/"],
"exclude": ["**/test/**", "**/mocks/**"],
"version": "0.8.20"
},
"vyper": {
"paths": ["vyper/"],
"version": "0.3.9"
},
"rust": {
"paths": ["programs/"],
"features": ["solana"]
}
},
"preset": "standard"
}
Path Configuration
Specify where each language lives:
{
"paths": {
"solidity": ["contracts/**/*.sol"],
"vyper": ["vyper/**/*.vy"],
"rust": ["programs/**/src/**/*.rs"]
}
}
Dependency Resolution
Solidity Dependencies
node_modules/@openzeppelin/
lib/forge-std/
Rust Dependencies
Cargo.lock defines exact versions
Cross-Dependencies
When languages share ABIs or interfaces:
shared/
├── abis/
│ └── IToken.json
├── solidity/
│ └── IToken.sol
└── rust/
└── token_interface.rs
CI/CD Integration
Multi-Language Workflow
name: Security Scan
on: [push, pull_request]
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# Install all language dependencies
- name: Setup Node
uses: actions/setup-node@v4
- run: npm install
- name: Setup Rust
uses: actions-rs/toolchain@v1
with:
toolchain: stable
- name: Setup Foundry
uses: foundry-rs/foundry-toolchain@v1
# Upload and scan all languages
- name: BlockSecOps Scan
run: |
zip -r project.zip contracts/ vyper/ programs/ \
node_modules/ lib/ Cargo.lock foundry.toml
# Upload and scan
blocksecops scan project.zip --preset standard
Best Practices
Consistent Patterns
Use similar patterns across languages:
| Pattern | Solidity | Vyper | Rust |
|---|---|---|---|
| Access Control | onlyOwner modifier |
assert msg.sender == owner |
require!(ctx.authority) |
| Checks-Effects-Interactions | Manual | Built-in | Manual |
| Safe Math | Built-in (0.8+) | Built-in | checked_* |
Interface Consistency
Keep interfaces synchronized:
// Solidity interface
interface IVault {
function deposit(uint256 amount) external returns (bool);
function withdraw(uint256 amount) external returns (bool);
}
# Vyper must match exactly
@external
def deposit(amount: uint256) -> bool:
...
@external
def withdraw(amount: uint256) -> bool:
...
Shared Testing
Test cross-language interactions:
describe("Cross-language integration", () => {
it("Solidity calls Vyper vault correctly", async () => {
// Test interface compatibility
});
});
Troubleshooting
Language Not Detected
- Check file extensions are correct
- Verify pragma/version comments present
- Include configuration files
Scanner Mismatch
- Specific scanner for one language may not apply to others
- Check scanner compatibility in catalog
- Use preset for automatic selection
Compilation Errors
- Each language may have different dependency requirements
- Include all necessary dependencies
- Check version compatibility
Next Steps
- Solidity Guide - Solidity specifics
- Vyper Guide - Vyper specifics
- Rust/Solana Guide - Rust specifics
- Framework Guides - Framework setup