# Withdrawals can be frozen by creating null deposits

Zero-liquidity deposits in Olas liquidity_lockbox create phantom positions that make the linear withdraw loop revert, freezing all LP withdrawals.

- Payout: Contest reward
- Severity: high
- Program: Olas
- Credited: erebus
- Disclosed: 2024-02-06
- Write-up quality: 7/10
- Original: https://github.com/code-423n4/2023-12-autonolas-findings/issues/341
- Library page: https://bugbountylibrary.com/r/c4%3A2023-12-autonolas%3AH-05
- Tags: domain:web3 impact:dos kind:contest platform:code4rena sev:high tech:solana tech:solidity technique:source-review vuln:business-logic vuln:dos

**Target:** Solana liquidity_lockbox Solidity contract (deposit/withdraw)
**Root cause:** _getPositionData only checks liquidity <= uint64 max, not > 0, so a zero-liquidity deposit is recorded in mapPositionAccountLiquidity and positionAccounts; withdraw treats liquidity==0 as nonexistent and reverts.
**Steps:**
1. Call deposit with positionData.liquidity = 0; passes _getPositionData bounds check.
2. Low-level transfer/mint calls fail silently (no success check), but position is still stored in mapPositionAccountLiquidity and positionAccounts.
3. Any withdraw() reads positionAccounts[firstAvailablePositionAccountIndex]; when it reaches the zero-liquidity position, `if (positionLiquidity == 0) revert("No liquidity on a provided token account")`.
4. firstAvailablePositionAccountIndex never increments past the bad entry, so all withdrawals revert.
**How found:** Noticed withdraw uses liquidity==0 as an existence sentinel for mapping lookups, then checked deposit validation and found only an upper-bound check, allowing a zero-liquidity position to be created and stored.
**Exploitation:** Attacker submits a deposit with zero liquidity; the phantom position is appended to the linear positionAccounts array. Because withdraw iterates linearly from firstAvailablePositionAccountIndex and reverts on liquidity==0, every subsequent withdrawal is blocked, freezing all LP funds.
**Insight:** When a mapping's zero value doubles as an existence sentinel, audit every write path for whether it can legitimately store zero; also check whether linear iteration over an append-only array can be poisoned by an entry that always reverts.
