audit: SAC compatibility audit for stealth-sender#43
Conversation
- Audit report at stellar/audits/2026-06-sac-compatibility.md - Adversarial mock SACs for each asset variant (standard, auth-required, auth-revocable, clawback, immutable-safe, immutable+auth-required, fee token) - Test harness at stealth-sender/tests/sac_compat.rs (9 tests) - Add rlib crate-type to stealth-sender for integration test imports Critical: AUTH_CLAWBACK_ENABLED and AUTH_REVOCABLE assets defeat unlinkability. AUTH_REQUIRED is a UX blocker. Recommend asset allowlist in stealth-sender.
|
@Faromzy Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits. You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀 |
|
This is the rigor I want for SAC compatibility. Seven mock token variants is exhaustive coverage of the realistic Stellar issuance flag combinations, and the verdict matrix gives us a clean go/no-go per asset type. The Clawback finding is the most important here. AUTH_CLAWBACK_ENABLED specifically defeats unlinkability because the issuer correlates announcement timing with the clawback target. That has to be on the "refuse at send time" list before mainnet. Next concrete step on the contract side is the allowlist enforcement in Also, please open the docs follow-up issue to surface this matrix in Thanks @Faromzy, real audit quality. |
audit: SAC compatibility audit for Stellar stealth-sender
Closes the unaudited security gap identified in the issue: stealth-sender calls
token::Client::transfer() with no checks on asset type or issuer flags.
What's in this PR
findings and the asset compatibility matrix
variants (standard, auth-required, auth-revocable, clawback-enabled,
immutable-safe, immutable+auth-required, custom fee token)
combination
imports
Key findings
┌──────────┬─────────┐
│ Severity │ Finding │
├──────────┼────────────────────────────────────────────────────────────────┤
│ Critical │ AUTH_CLAWBACK_ENABLED — issuer can reverse a stealth payment │
│ │ post-receipt, breaking unlinkability │
├──────────┼────────────────────────────────────────────────────────────────┤
│ High │ AUTH_REVOCABLE — issuer can freeze the stealth address balance │
│ │ after receipt │
├──────────┼────────────────────────────────────────────────────────────────┤
│ Medium │ AUTH_REQUIRED — stealth address must be pre-authorized by │
│ │ issuer; incompatible with stealth flows │
├──────────┼────────────────────────────────────────────────────────────────┤
│ Medium │ AUTH_IMMUTABLE + AUTH_REQUIRED — permanently broken, no │
│ │ remediation path │
├──────────┼────────────────────────────────────────────────────────────────┤
│ Low │ Custom fee tokens — announced amount ≠ received amount │
├──────────┼────────────────────────────────────────────────────────────────┤
│ Low │ No atomic rollback if announcer fails after transfer completes │
└──────────┴────────────────────────────────────────────────────────────────┘
Supported assets: native XLM, standard issued (no flags), AUTH_IMMUTABLE with
no clawback/auth-required.
Recommended follow-up (not in this PR): implement an asset allowlist in
stealth-sender with a TokenNotAllowed error — the only approach that covers
clawback, which has no pre-flight query in the SAC interface.
Testing
cd stellar && cargo test --package stealth-sender
closes #16