SSSwap

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

Unchecked Balance Transfer Vulnerability

Root + Impact

https://github.com/CodeHawks-Contests/2025-05-ssswap/blob/27a2ef878023b0111ec4acc33503d99ae1ae36fa/programs/amm/src/instructions/swap_operations.rs#L151-L158

Description

  • Normal Behavior: When performing token swaps, the user should only be able to swap up to the amount they own. The system should ensure that the user's balance is sufficient before proceeding with the transfer.

  • Specific Issue: In the swap_exact_in function, the code calls transfer_tokens without checking if the user has enough balance in token accounts like user_token_a or user_token_b. If the user's balance is insufficient, the transfer will fail, and the error reason might not be clear.

transfer_tokens(
&context.accounts.user_token_a,
&mut context.accounts.token_vault_a,
&amount_in,
&context.accounts.token_a,
&context.accounts.user,
&context.accounts.token_program,
)?; // @> No prior balance check before transfer

Risk

Likelihood:

  • This issue will inevitably occur when the user provides input (such as amount_in) and no balance check is performed beforehand.

  • The problem exists in the main execution path, and there is no error handling to address the insufficient balance scenario, which can affect user experience and complicate debugging.

Impact:

  • The transaction will fail, wasting computational resources (e.g., intermediate calculations are executed but the transaction is reverted).

  • Users will face unclear failure messages, which may lead them to believe the system is malfunctioning or that the pool is unavailable.

Proof of Concept

  • Assume user A has 5 tokenA, but amount_in = 100 is passed in the call

  • The contract will attempt to transfer 100 tokenA from user_token_a to token_vault_a

  • Anchor's transfer_checked will revert due to insufficient balance

  • No prior check for this failure scenario, resulting in unclear error messages

require(user_token_a.amount >= 100); // Missing this line, directly attempting transfer
transfer_checked(...); // Will revert

Recommended Mitigation

Add balance check logic before performing the transfer. For example:

if context.accounts.user_token_a.amount < amount_in {
return err!(AmmError::InsufficientFunds);
}

Additionally, the same check should be done for user_token_b depending on the zero_for_one condition. This would allow the transaction to be halted early, saving resources and providing clearer error messages.

Updates

Lead Judging Commences

0xtimefliez Lead Judge about 1 month ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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