Saber StableSwap
Summary
ExpandThe Saber StableSwap program demonstrates a generally strong security posture. Admin functions are properly gated with signer and key checks, PDA authority derivation is used consistently for swap-signed operations, arithmetic is protected by compile-time `deny(clippy::integer_arithmetic)` and runtime `checked_*` operations, and the initialization flow has thorough validation against reinitialization, delegate accounts, close authorities, and mint mismatches.
Two defense-in-depth issues were identified. The swap account's ownership is never validated against the program ID in read-only instruction handlers (swap, deposit, withdraw), and the token program account passed to CPIs is never validated against `spl_token::id()`. Both are mitigated by Solana runtime constraints (PDA authority requirements and account ownership enforcement respectively), but represent missing validation layers that could become exploitable in composable DeFi contexts or if runtime assumptions change.
The codebase uses well-structured validation macros, proper slippage protection on all user-facing operations, and a two-step admin transfer with time delay. The pause mechanism correctly allows balanced withdrawals during emergencies while blocking swaps, deposits, and imbalanced withdrawals.
Findings
1 issue identified
Swap state account owner not verified in user-facing instructions
stable-swap-program/program/src/processor/swap.rs:88
View Details
Description
The user-facing instruction handlers (process_swap, process_deposit, process_withdraw, process_withdraw_one) read the swap state from swap_info via SwapInfo::unpack() without first verifying that swap_info.owner == program_id. Pack::unpack only checks is_initialized — it does not enforce account ownership. An attacker can create a separate program that stores data in the SwapInfo layout with malicious parameters (e.g., 100% admin fees, attacker-controlled fee destinations), derive the corresponding PDA authority, and present the fake pool to users.
Impact
An attacker can create a fake swap pool with adversarial parameters that the StableSwap program will process as legitimate. Users tricked into submitting transactions referencing the fake swap account (via compromised frontend or phishing) could lose tokens deposited into the malicious pool.
Recommendation
Add swap_info.owner != program_id check at the start of each user-facing instruction handler after reading swap_info.
Fix
Adds an owner check on the swap_info account in all four user-facing instruction handlers (process_swap, process_deposit, process_withdraw, process_withdraw_one). This ensures the program only reads swap state from accounts it owns, preventing attackers from substituting fake state accounts created by other programs.
stable-swap-program/program/src/processor/swap.rs
Conclusion
ExpandThe Saber StableSwap codebase reflects strong engineering discipline, with clean separation of concerns between its mathematical core, state management, and instruction processing layers. The absence of critical or high-severity findings is notable for a DeFi primitive handling pooled token reserves. However, the identified medium-severity issue regarding swap state account owner verification represents a meaningful gap in the program’s trust boundary enforcement. Account ownership validation is a fundamental security invariant for Solana programs, and its absence in user-facing instruction paths — where untrusted accounts are supplied by external callers — constitutes a real and exploitable attack surface.
The development team should prioritize remediation of the medium-severity finding by adding explicit owner checks on the swap state account at the entry point of every public instruction that consumes it. This is a straightforward fix — typically a single conditional assertion — and should be deployed promptly given the direct impact on fund safety. Following remediation, a targeted re-audit of the patched code paths is recommended to confirm the fix is applied consistently and does not introduce regressions in the program’s account validation logic.
Legal Disclaimer: This report covers the code submitted for analysis. It does not account for infrastructure, deployment configuration, third-party dependencies, or changes made after the audit date. Automated analysis may produce false positives or miss context-dependent vulnerabilities. audited.xyz provides this report “as is” without warranty of any kind.