- Admin-only functions (
register_validator,update_config,deactivate_validator,update_validator_reputation) verify the caller matches the stored admin address - Non-admin callers receive
Error::Unauthorized - FIXED (SC-1):
initializenow has a guard against re-initialization usingenv.storage().instance().has(&DATA_KEY)check - Admin key rotation mechanism is not implemented; document the operational runbook for key compromise
-
confidenceandreputationvalues > 100 are rejected withError::InvalidInput - Boundary values 0 and 100 are accepted as valid
- FIXED (SC-3): Empty
reasonstring is now rejected withError::InvalidInput - FIXED (SC-2):
consensus_thresholdof 0 is rejected withError::InvalidInputinupdate_config
- Duplicate reports from the same validator for the same account are blocked via
Error::AlreadyReported - Unique validator counting in
is_fraudulentprevents a single address inflating consensus
- Reputation minimum enforced before accepting reports
- Configurable
consensus_thresholdrequires independent validators - REVIEW: Admin can register unlimited validators and immediately set high reputations — document trusted-setup assumption or add a time-lock
-
u8arithmetic for reputation/confidence cannot overflow standard addition since values are validated to ≤ 100 -
u64counters (report_count,accurate_reports) use saturating Soroban semantics - Confirm
consensus_thresholdcomparison (validator_count >= data.consensus_threshold) uses matching integer types to avoid sign-extension issues
- TTL / expiry of instance storage not configured — very old fraud reports persist indefinitely; consider archival strategy
- Single
DATA_KEYstorage is atomic per ledger operation; no partial-write risk
- FIXED (SC-4):
get_active_validatorsnow accepts an optionallimitparameter (default 100) to prevent unbounded iteration -
get_fraud_reportsiterates all reports per account — same concern for heavily-targeted accounts
- All raw SQL queries must use parameterised statements (SQLAlchemy ORM or
%splaceholders); auditastroml/db/for string-formatted queries - Graph construction paths that accept external filenames must be validated against a whitelist of allowed directories
-
config/database.yamlis listed in.gitignore(verify) - Ensure no credentials are hard-coded in source files (run
git grep -n "password\|secret\|api_key") - Database passwords should be read from environment variables, not YAML files checked into VCS
- Run
pip-auditagainstrequirements.txtto identify known CVEs - Pin all dependency versions and maintain a lock file (
pip-compile) - Rust dependencies: run
cargo auditagainstCargo.lock
- Pickle-based model serialisation (
torch.save/torch.load) must only load files from trusted paths; never load user-supplied model files directly
- Training labels must not be visible to the model during inference evaluation (covered by
tests/test_leakage.py) - Logged metrics / artefacts must not contain PII from Stellar account addresses in plaintext
- Hydra / YAML configs must validate types and ranges on load; reject unknown keys
-
consensus_thresholdand other thresholds inconfigs/should have documented acceptable ranges
- Base images pinned to digest, not floating tags
- Container does not run as root (
USERdirective set inDockerfile) - No secrets in
docker-compose.ymlenvironment blocks in plaintext
- Add
cargo auditstep to CI pipeline - Add
pip-auditorsafety checkstep to CI pipeline - Secret scanning (e.g.,
git-secretsor GitHub secret scanning) enabled on the repository
| ID | Severity | Finding | Status |
|---|---|---|---|
| SC-1 | High | __init__ can be called again, overwriting admin |
Resolved |
| SC-2 | Medium | consensus_threshold = 0 marks all accounts fraudulent |
Resolved |
| SC-3 | Low | Empty reason string accepted |
Resolved |
| SC-4 | Medium | get_active_validators unbounded iteration |
Resolved |
| PY-1 | High | Confirm no hard-coded credentials in source | Open |
| PY-2 | High | Run pip-audit; remediate CVE findings |
Open |
| PY-3 | Medium | Pickle load from untrusted path | Open |
| IN-1 | Medium | Docker base image tags not pinned to digest | Open |