# Attacker can lock every trove withdrawals

Sentinel's convert_to_yang applies a deposit cap check (addition) during withdrawals, so an attacker filling a gate to max_amt blocks all trove withdrawals.

- Payout: Contest reward
- Severity: medium
- Program: Opus
- Credited: zigtur
- Disclosed: 2024-03-08
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2024-01-opus-findings/issues/29
- Library page: https://bugbountylibrary.com/r/c4%3A2024-01-opus%3AM-08
- Tags: domain:web3 impact:dos kind:contest platform:code4rena sev:medium tech:solidity technique:source-review vuln:business-logic vuln:dos

**Target:** Abbot/Sentinel withdrawal flow (Cairo contracts)
**Root cause:** withdraw() calls sentinel.convert_to_yang, which invokes assert_can_enter checking current_total + enter_amt <= max_amt; for a withdrawal this should subtract, so any state at the cap reverts.
**Steps:**
1. Deploy abbot/sentinel with a gate whose asset balance equals max_amt (or deposit until current_total == max_amt).
2. Call `abbot.withdraw(trove_id, AssetBalance{address: asset_addr, amount: 1})`.
3. convert_to_yang -> assert_can_enter computes current_total + 1 > max_amt and reverts with 'SE: Exceeds max amount allowed'.
4. All users' withdrawals for that yang revert until admin raises the cap.
**How found:** Code reading of the withdraw path: noticed convert_to_yang is reused for withdrawals and that assert_can_enter always adds enter_amt, which is wrong direction for exits; confirmed with a unit test setting max to current gate balance.
**Exploitation:** Attacker deposits asset into the gate until current_total reaches max_amt, sacrificing their own funds (locked too), making every trove withdrawal of that yang revert until admin reconfigures the max.
**Insight:** When a shared conversion/validation helper is reused across deposit and withdraw paths, check whether its cap/limit assertion assumes inflow direction; equality-at-cap states are the cheapest trigger.
