# A huge loss of funds for all the users who try to remove liquidity after swapping got disabled at manipulated price.

When an asset's tradability is set to remove/add-liquidity-only at a manipulated price, remove_liquidity skips the price check and charges a 100% withdrawal fee, zeroing LPs.

- Payout: Contest reward
- Severity: medium
- Program: HydraDX
- Credited: castle\_chain
- Disclosed: 2024-04-10
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2024-02-hydradx-findings/issues/22
- Library page: https://bugbountylibrary.com/r/c4%3A2024-02-hydradx%3AM-10
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:medium tech:solidity technique:source-review vuln:business-logic vuln:oracle-manipulation

**Target:** omnipool pallet remove_liquidity / set_asset_tradable_state (Substrate Rust)
**Root cause:** is_safe_withdrawal() treats REMOVE_LIQUIDITY-only tradability as safe, bypassing ensure_price, so calculate_withdrawal_fee clamps to 1.0 when spot/oracle diverge and fee_complement zeroes all returned amounts.
**Steps:**
1. Manipulate an asset's spot price so spot vs oracle EMA diverges.
2. Authority sets tradable state to ADD_LIQUIDITY|REMOVE_LIQUIDITY (swaps disabled) while price is off.
3. LP calls remove_liquidity; ensure_price is skipped due to safe_withdrawal=true.
4. calculate_withdrawal_fee returns price_diff/oracle_price clamped to 1.0.
5. fee_complement=0 zeroes delta_reserve, delta_hub_reserve, hub_transferred; LP receives nothing.
**How found:** Code reading of remove_liquidity's safe_withdrawal branch and calculate_withdrawal_fee clamp; noticed ensure_price is skipped when swaps disabled, and that tradability can be set at a manipulated price.
**Exploitation:** Precondition: asset tradability set to remove/add-only while spot price is manipulated away from oracle. LP withdrawal then pays 100% fee with no revert and no user slippage guard, redistributing shares to other LPs.
**Insight:** When a protocol skips oracle checks under a 'safe mode' flag, check whether that flag can be toggled while price is already off-oracle; fee formulas clamped to 1.0 silently confiscate principal instead of reverting.
