sherlock-audit / 2024-08-woofi-solana-deployment-judging

0 stars 0 forks source link

Strong Alabaster Leopard - claim_fee will be reverted because of insufficient balance #68

Open sherlock-admin4 opened 13 hours ago

sherlock-admin4 commented 13 hours ago

Strong Alabaster Leopard

High

claim_fee will be reverted because of insufficient balance

Summary

woopool_to'reserve and woopool_quote'reserve will be checked in every swap to has enough balance for user's swap and fee the protocl but mailicious user can bypass this constraints

Root Cause

swap_fee and to_amount compare with woopool_quote'reserve and woopool_to'reserve seperately which can be problematic

Internal pre-conditions

woopool_to's reserve = 990 fee_rate = 1% price=$1 user's from_amount = 1000

PoC

user calls swap function with this parameters [ woopool_from : woopool_usdt woopool_to : woopool_usdc woopool_quote: woopool_usdc from_amount: 1000 usdt min_to_amount:990 usdc ]

quote_amount = base_amount * price = 1000 1 = 1000 usdc `fee_swap = quote_amount fee_rate= 1000 * 1/100 = 10 usdc quote_amount = quote_amount - fee_swap` = 1000 - 10 = 990 usdc

pub fn handler(ctx: Context<Swap>, from_amount: u128, min_to_amount: u128) -> Result<()> {
    let price_update_from = &mut ctx.accounts.price_update_from;
    let price_update_to = &mut ctx.accounts.price_update_to;
    ...
    if woopool_from.token_mint != woopool_from.quote_token_mint {
        require!(
@>>>            woopool_quote.reserve  >= swap_fee && quote_token_vault.amount as u128 >= swap_fee,
            ErrorCode::NotEnoughOut
        );
        ...
    require!(
@>>>         woopool_to.reserve >= to_amount && token_vault_to.amount as u128 >= to_amount,
         ErrorCode::NotEnoughOut
     );
        );
    }

both constraints will be passed because 990 is greater than 10 and also is greater and equal 990 finally 990 usdc sent to user from usdcpool its mean woopool_to reserve become 0 and after that, the admin calls claim_fee but his transaction will be reverted becuase token vault balance is zero[pool_reserve = 0, unclaimed_fee = 10 usdc,token_value_amount = 0]

Code Snippet

https://github.com/sherlock-audit/2024-08-woofi-solana-deployment/blob/main/WOOFi_Solana/programs/woofi/src/instructions/swap.rs#L156

https://github.com/sherlock-audit/2024-08-woofi-solana-deployment/blob/main/WOOFi_Solana/programs/woofi/src/instructions/swap.rs#L183

https://github.com/sherlock-audit/2024-08-woofi-solana-deployment/blob/main/WOOFi_Solana/programs/woofi/src/instructions/admin/claim_fee.rs#L41

Impact

claim_fee will be reverted because of insufficient balance

Mitigation

+            woopool_quote.reserve  >= swap_fee && quote_token_vault.amount as u128 >= swap_fee,
+            ErrorCode::NotEnoughOut
+        );
+    }
+
+    if(woopool_quote.key() == woopool_to.key()){
+        require!(
+            woopool_quote.reserve  >= swap_fee + quote_amount && quote_token_vault.amount as u128 >= swap_fee + quote_amount,
             ErrorCode::NotEnoughOut
         );