When withdrawing, the check that balance is enough for unclaimed fees is wrong
Summary
When withdrawing, the check that there is enough balance for unclaimed fees is wrong. It does not prevent withdrawing funds from the token vault so there is enough balance for unclaimed fees.
Since the check is done before the withdrawal and not after, funds can be withdrawn so that there will not be enough for unclaimed fees.
A pool can have a token vault balance that is lower than the sum of the pool reserve and unclaimed fees due to the incase_token_got_stuck instruction.
Root Cause
In token.rs:12-14, the quote pool's vault is checked that it has enough balance for unclaimed fees.
(token_vault.amount as u128)
.checked_sub(woopool.unclaimed_fee)
.ok_or(ErrorCode::ReserveLessThanFee)?
However, the check is done before withdrawal and it does not account for the withdrawal amount.
let _balance_before = balance(woopool, token_vault)?;
Since the Pool owner has deducted funds with incase_token_got_stuck, the Pool now has a token vault balance of 100, 100 pool reserves, and 20 unclaimed fees.
The Pool owner withdraws 100 tokens and this is not prevented since the check that balance is enough for unclaimed funds is insufficient.
Impact
If the Pool owner wants to withdraw without regard for unclaimed fees and reserves, they can always use incase_token_got_stuck. All withdrawals via withdraw should ensure enough vault funds for at least the unclaimed fees.
PoC
No response
Mitigation
Consider using the _balance_before in the check for enough balance when withdrawing.
Glamorous Violet Chameleon
Medium
When withdrawing, the check that balance is enough for unclaimed fees is wrong
Summary
When withdrawing, the check that there is enough balance for unclaimed fees is wrong. It does not prevent withdrawing funds from the token vault so there is enough balance for unclaimed fees.
Since the check is done before the withdrawal and not after, funds can be withdrawn so that there will not be enough for unclaimed fees.
A pool can have a token vault balance that is lower than the sum of the pool reserve and unclaimed fees due to the
incase_token_got_stuck
instruction.Root Cause
In
token.rs:12-14
, the quote pool's vault is checked that it has enough balance for unclaimed fees.However, the check is done before withdrawal and it does not account for the withdrawal amount.
Internal pre-conditions
incase_token_got_stuck
.External pre-conditions
None
Attack Path
incase_token_got_stuck
, the Pool now has a token vault balance of 100, 100 pool reserves, and 20 unclaimed fees.withdraws
100 tokens and this is not prevented since the check that balance is enough for unclaimed funds is insufficient.Impact
If the Pool owner wants to withdraw without regard for unclaimed fees and reserves, they can always use
incase_token_got_stuck
. All withdrawals viawithdraw
should ensure enough vault funds for at least the unclaimed fees.PoC
No response
Mitigation
Consider using the
_balance_before
in the check for enough balance when withdrawing.