# Attacker can censor liquidity providers deposits and withdrawals by front-running

Omnipool's depositFor lets an attacker set lastTransactionBlock for any victim address, blocking their deposits and withdrawals within the same block.

- Payout: Contest reward
- Severity: high
- Program: Opal
- Credited: zigtur
- Disclosed: 2024-03-30
- Write-up quality: 6/10
- Original: https://cdn.cantina.xyz/reports/cantina_competition_opal_feb2024.pdf#3.2.2
- Library page: https://bugbountylibrary.com/r/cantina%3Aopal_feb2024%3A3.2.2
- Tags: domain:web3 impact:dos kind:contest platform:cantina sev:high tech:evm tech:solidity technique:source-review vuln:business-logic vuln:dos

**Target:** Omnipool.sol depositFor/withdraw (Solidity smart contract)
**Root cause:** depositFor updates lastTransactionBlock[_depositFor] for an attacker-controlled recipient address, and the same mapping gates withdraw for msg.sender, so a third party can pre-set the victim's block marker.
**Steps:**
1. Attacker calls `depositFor(smallAmount, victimAddress, 0)` with a tiny underlyingToken amount, setting `lastTransactionBlock[victim] = block.number`.
2. Victim's subsequent `depositFor` or `withdraw` in the same block reverts with `CantDepositAndWithdrawSameBlock()`.
3. No minimum deposit amount means the griefing cost is negligible; repeat each block to censor.
**How found:** Code review of depositFor/withdraw noticed the lastTransactionBlock check keyed on _depositFor (attacker-controlled) rather than msg.sender, and that no minimum deposit amount exists.
**Exploitation:** Front-run victim deposit/withdraw transactions each block by submitting a cheap depositFor to the victim's address, forcing their transactions to revert and locking funds.
**Insight:** When a per-address anti-abuse mapping is written using a caller-supplied recipient parameter instead of msg.sender, any third party can poison that address's state; check every mapping write keyed on user-supplied addresses.
