# Flash loan repayment not verified

Flash loan callbacks that never compare pool balance before and after to confirm repayment

_Area: DeFi oracles, liquidations and flash loans. Seen in 2 disclosed reports; latest 2022-12-21. Updated 2026-10-30._

## How it works
A flash loan pays out funds, calls back into the borrower, then expects the funds plus a fee back. The property that must hold is that the pool's balance after the callback is at least the balance before plus the fee. When the code instead trusts the success of a transfer call, or trusts that the callback repaid, that invariant is never measured. A token that reports success without moving funds, or a callback that simply returns, leaves the loan unreturned while the pool releases value.

## Where it shows up
- `flashLoan`/`flashSwap` functions with no before/after balance comparison around the callback.
- Repayment verified only by `safeTransferFrom`/`transfer` success or by absence of revert [E1](https://bugbountylibrary.com/r/sherlock%3A2023-01-ajna%3AM-13.md).
- Callback invoked before the outbound transfer, so the borrower never holds the funds [E3](https://bugbountylibrary.com/r/c4%3A2021-09-sushitrident%3AH-01.md).
- Token `transfer` logic that may mishandle self-transfers or repeated transfers, inflating balances [E2](https://bugbountylibrary.com/r/dhl%3A20241210-labubu.md).
- Upgradable tokens that may later add freeze/blacklist behavior, turning a transfer into a silent no-op [E1](https://bugbountylibrary.com/r/sherlock%3A2023-01-ajna%3AM-13.md).

## How to review
State the invariant explicitly: pool balance after callback >= balance before + fee, in the loaned token. Confirm the code snapshots the balance before the callback and compares it after, reverting otherwise [E1](https://bugbountylibrary.com/r/sherlock%3A2023-01-ajna%3AM-13.md). Check ordering: the outbound transfer must precede the callback so the borrower actually holds funds [E3](https://bugbountylibrary.com/r/c4%3A2021-09-sushitrident%3AH-01.md). Confirm repayment does not rest on transfer return values alone [E1](https://bugbountylibrary.com/r/sherlock%3A2023-01-ajna%3AM-13.md). Treat caller-supplied tokens, amounts and calldata as a separate input-validation concern, not proof of repayment.

## Variants seen
- No balance-delta check; repayment relies on `safeTransferFrom` success [E1](https://bugbountylibrary.com/r/sherlock%3A2023-01-ajna%3AM-13.md).
- Callback fires before tokens are transferred out, breaking the swap [E3](https://bugbountylibrary.com/r/c4%3A2021-09-sushitrident%3AH-01.md).
- Token-level transfer accounting flaw suspected of enabling balance inflation across flash-loaned self-transfers [E2](https://bugbountylibrary.com/r/dhl%3A20241210-labubu.md).

## Impact and severity
High to critical where repayment is unverified: the loan can go unreturned, putting pool liquidity at risk [E1](https://bugbountylibrary.com/r/sherlock%3A2023-01-ajna%3AM-13.md). Severity rises when tokens are upgradable, since a previously safe transfer can later become a no-op [E1](https://bugbountylibrary.com/r/sherlock%3A2023-01-ajna%3AM-13.md). The ordering bug silently breaks the feature rather than draining it [E3](https://bugbountylibrary.com/r/c4%3A2021-09-sushitrident%3AH-01.md). The token accounting case is suspected, not confirmed, and netted 17.4 BNB [E2](https://bugbountylibrary.com/r/dhl%3A20241210-labubu.md).

## Evidence
- E1: https://bugbountylibrary.com/r/sherlock%3A2023-01-ajna%3AM-13.md
- E2: https://bugbountylibrary.com/r/dhl%3A20241210-labubu.md
- E3: https://bugbountylibrary.com/r/c4%3A2021-09-sushitrident%3AH-01.md
