# Flash loan fee and repayment accounting gaps

Callback repays full amount without reserving fee; balance-delta check missing after flash loan

_Area: DeFi oracles, liquidations and flash loans. Seen in 2 disclosed reports; latest 2025-02-17. Updated 2026-10-25._

## How it works
A flash loan callback receives borrowed funds, does work, and must return principal plus fee before the transaction ends. The assumption that breaks: the code treats the borrowed amount as fully available for its own repayment or accounting, forgetting the fee must come out of the same balance. If the callback spends or repays the entire received amount, no balance remains for the fee, so the lender's repayment check fails or the contract reverts. The same root cause appears when a gate is satisfied by a temporary balance that is never validated as persistent: the check reads a balance or health factor at one instant, and nothing requires it to survive the callback.

## Where it shows up
- Callback handlers that repay `subDebt` or the full borrowed constant without subtracting the lender fee.
- Approvals or allowance fixes that add the fee but leave the repayment/accounting path unchanged.
- Health or solvency gates evaluated only at transaction time, with permissionless supply/withdraw in the same flow.
- Token transfer logic where self-transfers or repeated transfers update balances without cost.
- Missing post-callback balance-delta assertion (balance after >= balance before + fee).

## How to review
The invariant: after the callback, the contract's balance must cover principal plus fee, and any gate must reflect collateral that persists beyond the transaction. Check that the repayment amount is derived from the actual received balance minus the fee, not from a constant. Confirm a balance-delta check exists after the callback. For gates, verify the health factor cannot be satisfied by funds supplied and withdrawn within one transaction, or that a time-lock/persistence requirement exists.

## Variants seen
- Fee omitted from repayment accounting, causing guaranteed revert when fee>0; prior fix only touched approvals [E1](https://bugbountylibrary.com/r/c4%3A2024-10-loopfi%3AM-01.md).
- Instantaneous health check passed by flash-loan-funded temporary collateral, then unwound [E2](https://bugbountylibrary.com/r/c4%3A2022-11-paraspace%3AH-07.md).
- Token transfer accounting flaw allowing balance inflation via repeated self-transfers funded by flash loan [E3](https://bugbountylibrary.com/r/dhl%3A20241210-labubu.md).

## Why fixes fail
E1 shows a fix that added the fee to approvals but not to the repayment path, leaving the revert in place. Approvals alone do not create balance; the accounting must reserve the fee.

## Impact and severity
E1 caused a core function to always revert (denial of functionality). E2 let a user bypass an auction recovery gate, undermining liquidation protection. E3 netted 17.4 BNB through inflated balances. Severity rises where the gap enables fund extraction or bypasses solvency gates rather than only reverting.

## Evidence
- E1: https://bugbountylibrary.com/r/c4%3A2024-10-loopfi%3AM-01.md
- E2: https://bugbountylibrary.com/r/c4%3A2022-11-paraspace%3AH-07.md
- E3: https://bugbountylibrary.com/r/dhl%3A20241210-labubu.md
