# Self-liquidation profit extraction

Can one actor be borrower and liquidator, and does the bonus or internal price exceed the trigger cost?

_Area: DeFi oracles, liquidations and flash loans. Seen in 3 disclosed reports; latest 2026-08-28. Updated 2026-10-24._

## How it works
Liquidation is meant to be a third-party service: someone else closes an unhealthy position and is paid a bonus. The assumption that breaks is that borrower and liquidator are distinct actors with opposing interests. When one actor controls both sides, the bonus is a transfer from the pool to themselves. In oracle-free designs the settlement price derives only from pool internal state, so the same actor shapes the price on both ends and can extract more collateral than the debt is worth [E1](https://bugbountylibrary.com/r/dhl%3A20260828-ajnafinance.md). Self-liquidation can also reach states that normal exit paths block, such as bypassing efficiency and liquidity limits [E2](https://bugbountylibrary.com/r/sherlock%3A2023-10-perennial%3AM-2.md).

## Where it shows up
- Liquidation entry points with no check that `msg.sender != borrower` [E3](https://bugbountylibrary.com/r/dhl%3A20260310-alkemiearn.md).
- Oracle-free or internal-state-only pricing for auctions or buckets, with no external feed to contradict a manipulated price [E1](https://bugbountylibrary.com/r/dhl%3A20260828-ajnafinance.md).
- Margin checks using a looser threshold (maintained) on one path and a stricter one (margined) on another [E2](https://bugbountylibrary.com/r/sherlock%3A2023-10-perennial%3AM-2.md).
- Borrow balances changeable in the same transaction as the liquidation, especially with flash-loan capital [E3](https://bugbountylibrary.com/r/dhl%3A20260310-alkemiearn.md).

## How to review
The invariant: for any liquidation, the liquidator must not be the borrower or an entity the borrower controls, and the price used to settle must not be settable by either party. Check the stricter margin threshold applies on every path that can change position or collateral [E2](https://bugbountylibrary.com/r/sherlock%3A2023-10-perennial%3AM-2.md). For oracle-free designs, ask whether one actor can be both borrower and taker and shape the internal price [E1](https://bugbountylibrary.com/r/dhl%3A20260828-ajnafinance.md). Confirm the liquidation bonus cannot exceed the cost of triggering plus any price movement the actor causes.

## Variants seen
- Self-controlled Dutch auction in an oracle-free pool, manipulating internal bucket prices to seize collateral for far less than its value [E1](https://bugbountylibrary.com/r/dhl%3A20260828-ajnafinance.md).
- Self-liquidation in one transaction after committing a favorable oracle price, to bypass efficiency and liquidity limits [E2](https://bugbountylibrary.com/r/sherlock%3A2023-10-perennial%3AM-2.md).
- Direct self-liquidation with an inflated borrow balance funded by a flash loan [E3](https://bugbountylibrary.com/r/dhl%3A20260310-alkemiearn.md).

## Why fixes fail
E2 shows a prior fix (issue 104) that only guarded the pending position with the margined check while the settled position still used the maintained amount, leaving the self-liquidation path open.

## Impact and severity
Losses ranged from a single pool drained of ~48 cbETH (~$124.8K) [E1](https://bugbountylibrary.com/r/dhl%3A20260828-ajnafinance.md) to 43.45 ETH [E3](https://bugbountylibrary.com/r/dhl%3A20260310-alkemiearn.md). Severity is high where the bonus or internal price distortion is large relative to trigger cost, and worse when flash loans remove capital constraints [E3](https://bugbountylibrary.com/r/dhl%3A20260310-alkemiearn.md) or when the design has no external oracle to anchor prices [E1](https://bugbountylibrary.com/r/dhl%3A20260828-ajnafinance.md).

## Evidence
- E1: https://bugbountylibrary.com/r/dhl%3A20260828-ajnafinance.md
- E2: https://bugbountylibrary.com/r/sherlock%3A2023-10-perennial%3AM-2.md
- E3: https://bugbountylibrary.com/r/dhl%3A20260310-alkemiearn.md
