# It is possible to frontrun liquidations with self liquidation with high strain value to clear warning and keep unhealthy positions from liquidation

Any liquidation, even a self-liquidation with huge strain that leaves the position unhealthy, clears the warn timer, letting borrowers frontrun liquidators and block liquidation indefinitely.

- Payout: Contest reward
- Severity: high
- Program: Aloe
- Credited: panprog
- Disclosed: 2023-10-11
- Write-up quality: 7/10
- Original: https://github.com/sherlock-audit/2023-10-aloe-judging/issues/29
- Library page: https://bugbountylibrary.com/r/sherlock%3A2023-10-aloe%3AH-1
- Tags: domain:web3 impact:funds-loss kind:contest platform:sherlock sev:high tech:solidity technique:race-window technique:source-review vuln:business-logic vuln:dos vuln:liquidation

**Target:** Borrower.sol liquidation/warn logic in Aloe II core lending protocol
**Root cause:** Borrower.liquidate unconditionally resets slot0 to SLOT0_DIRT, clearing the warn timestamp regardless of post-repayment health or strain amount, so a near-zero-effect self-liquidation wipes the grace-period warning.
**Steps:**
1. Open a borrow position at minimum margin via `account.modify(this, abi.encode(Action.BORROW, borrows0, borrows1), (1<<32))`.
2. Call `account.warn((1<<32))` to set unleashLiquidationTime = now + LIQUIDATION_GRACE_PERIOD.
3. Wait LIQUIDATION_GRACE_PERIOD+1, then frontrun the pending liquidator tx with `account.liquidate(this, bytes(""), 1e10, (1<<32))` using a very high strain value so the position is essentially unchanged but still unhealthy.
4. Observe slot0 warn bits reset to 0; the liquidator's `account.liquidate(this, bytes(""), 1, (1<<32))` now reverts with 'Aloe: grace'.
5. Repeat every 2 minutes to keep the position permanently unliquidatable.
**How found:** Code reading of Borrower.warn vs Borrower.liquidate: noticed warn sets a timestamp but liquidate clears slot0 unconditionally without checking post-liquidation health or strain, then wrote a Foundry test to confirm the warn bits reset and the follow-up liquidation reverts.
**Exploitation:** Borrower monitors the mempool for liquidation txs (or races at grace expiry) and submits a self-liquidation with a huge strain parameter that repays a negligible amount, clearing the warn state and forcing the liquidator's tx to revert. Repeating every 2 minutes keeps an underwater position alive until it accrues bad debt, leaving later depositors unable to withdraw.
**Escalation:** Attacker can hold large risky positions indefinitely; combined with volatility manipulation issues, bad debt can be forced, causing protocol insolvency and a bank run.
**Insight:** When a protocol gates an action behind a warning/timer, check whether the guarded action itself (or a self-service variant with attacker-controlled parameters like strain) resets that timer without validating the resulting state; a no-op self-call can be used to perpetually reset the gate.
