SSSwap

First Flight #41
Beginner FriendlyRust
100 EXP
View results
Submission Details
Impact: low
Likelihood: medium
Invalid

preview_swap

Root + Impact

Description

  • Describe the normal behavior in one or more sentences

  • Explain the specific issue or problem in one or more sentences

// Root cause in the codebase with @> marks to highlight the relevant section
Normal behavior:
The protocol’s swap operations normally allow users to exchange tokens with slippage protection and fee collection based on on-chain liquidity pool reserves. Typically, AMMs provide view functions such as preview_swap or get_price that allow users and integrators to estimate swap outputs or prices without executing a transaction.
Issue:
This protocol currently lacks view functions for simulating swap outcomes or querying current prices. As a result, frontends and external protocols cannot retrieve reliable, on-chain swap estimations directly. This forces clients to either duplicate the internal swap math off-chain (which may diverge due to rounding or future updates) or to risk inaccurate price information, which can lead to poor UX, failed swaps, or mispriced transactions.
// Root cause conceptual example in swap_operations.rs (pseudo-Rust)
pub fn swap_exact_in(ctx: Context<Swap>, amount_in: u64, min_amount_out: u64) -> ProgramResult {
// Calculate amount out according to constant product formula
let amount_out = calculate_swap_amount_out(...);
// > Missing preview function to simulate this calculation without state changes
// e.g. pub fn preview_swap_exact_in(...) -> u64 { ... }
require!(amount_out >= min_amount_out, ErrorCode::SlippageExceeded);
// proceed with token transfers and reserve updates
...
}
Impact
-Users risk submitting swaps with unexpectedly poor outcomes or failed transactions due to inaccurate pricing.
-Frontend applications cannot provide accurate swap previews, increasing user friction.
-External integrators (aggregators, bots, wallets) must rely on approximate off-chain math, leading to possible price mismatches.

Risk

Likelihood:

  • Reason 1 // Describe WHEN this will occur (avoid using "if" statements)

    This issue will occur whenever frontends or external integrations attempt to provide accurate swap price previews or slippage estimates using on-chain data.

  • Reason 2

    It happens consistently because the protocol does not expose any read-only functions to simulate swaps or fetch current pool prices directly from the contract.

Impact:

  • Impact 1

    External protocols and aggregators may display incorrect pricing information, potentially leading to poor trading decisions or loss of user trust in the platform.

  • Impact 2

    Users may submit swap transactions with unexpected outcomes, resulting in failed transactions or higher slippage than anticipated

Proof of Concept

The protocol does not expose any preview_swap or get_price functions in its program interface (lib.rs or swap_operations.rs).

A user or frontend calls the protocol to get a swap output estimate before submitting a swap transaction.

// Solidity-style pseudocode illustrating missing preview function
contract AMM {
mapping(address => uint256) public reserveA;
mapping(address => uint256) public reserveB;
// Existing swap function (state-changing)
function swapExactIn(uint256 amountIn, uint256 minAmountOut) external {
uint256 amountOut = calculateSwapAmountOut(amountIn);
require(amountOut >= minAmountOut, "Slippage exceeded");
// Transfer tokens and update reserves (state change)
// ...
}
// <-- Missing view function to preview swap amount out without state changes
// function previewSwapExactIn(uint256 amountIn) external view returns (uint256) {
// return calculateSwapAmountOut(amountIn);
// }
}
// Without previewSwapExactIn, frontends cannot query expected output safely.

Recommended Mitigation

- remove this code
N/A — this recommendation only adds new code.
+ add this code
// Add a view function to preview swap output for exact input amount
pub fn preview_swap_exact_in(ctx: Context<PreviewSwap>, amount_in: u64) -> Result<u64> {
let pool = &ctx.accounts.liquidity_pool;
// replicate constant product formula calculation
let amount_out = calculate_swap_amount_out(pool, amount_in)?;
Ok(amount_out)
}
// Similarly, add preview for exact output swaps
pub fn preview_swap_exact_out(ctx: Context<PreviewSwap>, amount_out: u64) -> Result<u64> {
let pool = &ctx.accounts.liquidity_pool;
// calculate required amount_in to get amount_out
let amount_in = calculate_swap_amount_in(pool, amount_out)?;
Ok(amount_in)
}
To improve usability and reduce incorrect swap estimates, implement read-only functions that simulate swaps without changing state. These functions provide accurate on-chain price previews, helping frontends and external tools avoid user errors, failed transactions, and integration issues, while boosting protocol trust and composability.Adding read-only preview functions lets users and integrators safely query expected swap results without executing a transaction or altering the protocol state. This reduces reliance on off-chain approximations, prevents user errors due to inaccurate price estimates, and improves the overall user experience. Moreover, it enables better integration with wallets and DeFi tools by providing reliable, on-chain pricing data, which increases trust and composability within the ecosystem.
Updates

Lead Judging Commences

0xtimefliez Lead Judge 5 days ago
Submission Judgement Published
Invalidated
Reason: Known issue

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.