Goal
Expand the scanner's cryptography coverage. The detectors below are on the roadmap and not yet implemented — each one is an independent, self-contained piece of work.
These are ready to pick up today. Every entry already has a committed test fixture pair under test-contracts/, so the expected behaviour is pinned before you write a line of code: the scanner must report a finding on the -vulnerable crate and stay silent on the -safe one. You are not guessing at requirements.
| Detector |
Fixture (under test-contracts/) |
crypto_no_cache |
crypto-no-cache-vulnerable / crypto-no-cache-safe |
ed25519_unchecked |
ed25519-unchecked-vulnerable / ed25519-unchecked-safe |
keccak_misuse |
keccak_misuse-vulnerable / keccak_misuse-safe |
How to build one
Pick one detector from the table and claim it in a comment. One detector per PR — that keeps review fast and lets several people work in parallel.
- Create
crates/checks/src/<name>.rs.
- Implement the
Check trait — name() and run(&self, file: &syn::File, source: &str) -> Vec<Finding>. crates/checks/src/auth.rs is the reference implementation to model: it uses syn::visit::Visit to walk function bodies and crate::util::contractimpl_functions to enumerate #[contractimpl] methods.
- Register it in
crates/checks/src/lib.rs in all three places, or it will compile but never run:
pub mod <name>;
pub use <name>::<Struct>;
Box::new(<Struct>) inside default_checks()
- Add unit tests in a
#[cfg(test)] module in your file.
- Verify against the fixtures:
cargo build --release
./target/release/soroban-guard scan test-contracts/<name>-vulnerable # must report your finding
./target/release/soroban-guard scan test-contracts/<name>-safe # must not
Acceptance criteria
- Fires on the
-vulnerable fixture, silent on the -safe one.
- Unit tests cover at least one positive and one negative case.
- Severity is justified in the PR description.
cargo fmt, cargo clippy -- -D warnings and cargo test are clean.
Notes on quality
A good detector is precise, not just present. Aim for:
- Low false positives. Flagging correct code is worse than missing a bug — it trains people to ignore the tool. The
-safe fixture is the floor, not the target; think about what other legitimate patterns could trip your logic.
- Actionable descriptions. The
description field should tell the reader what an attacker can actually do, not restate the rule. Compare "missing require_auth" against "Callers may mutate contract state without proving they are authorized."
- Set
check_name, severity, line and function_name. Leave file_path empty — the analyzer fills it in.
Goal
Expand the scanner's cryptography coverage. The detectors below are on the roadmap and not yet implemented — each one is an independent, self-contained piece of work.
These are ready to pick up today. Every entry already has a committed test fixture pair under
test-contracts/, so the expected behaviour is pinned before you write a line of code: the scanner must report a finding on the-vulnerablecrate and stay silent on the-safeone. You are not guessing at requirements.test-contracts/)crypto_no_cachecrypto-no-cache-vulnerable/crypto-no-cache-safeed25519_uncheckeded25519-unchecked-vulnerable/ed25519-unchecked-safekeccak_misusekeccak_misuse-vulnerable/keccak_misuse-safeHow to build one
Pick one detector from the table and claim it in a comment. One detector per PR — that keeps review fast and lets several people work in parallel.
crates/checks/src/<name>.rs.Checktrait —name()andrun(&self, file: &syn::File, source: &str) -> Vec<Finding>.crates/checks/src/auth.rsis the reference implementation to model: it usessyn::visit::Visitto walk function bodies andcrate::util::contractimpl_functionsto enumerate#[contractimpl]methods.crates/checks/src/lib.rsin all three places, or it will compile but never run:pub mod <name>;pub use <name>::<Struct>;Box::new(<Struct>)insidedefault_checks()#[cfg(test)]module in your file.Acceptance criteria
-vulnerablefixture, silent on the-safeone.cargo fmt,cargo clippy -- -D warningsandcargo testare clean.Notes on quality
A good detector is precise, not just present. Aim for:
-safefixture is the floor, not the target; think about what other legitimate patterns could trip your logic.descriptionfield should tell the reader what an attacker can actually do, not restate the rule. Compare "missing require_auth" against "Callers may mutate contract state without proving they are authorized."check_name,severity,lineandfunction_name. Leavefile_pathempty — the analyzer fills it in.