Flash loan attacks in disclosed bug bounty reports
Flash loans are not the vulnerability — they are the capital that makes an otherwise theoretical economic assumption break inside one transaction.
- Reports indexed
- 32
- Total paid
- $75k
- Critical
- 0
- Largest payout
- $75k
A flash loan turns any atomic economic assumption into a testable one. Protocols that would be safe against an attacker holding one percent of supply are not safe against an attacker who can hold ninety percent of it for the duration of a single call and give it back before the block closes.
Almost every report filed under this class is really a composite: a flash loan plus a price oracle that can be moved, or a flash loan plus governance weight counted at the current block, or a flash loan plus a reward curve that pays on instantaneous share rather than on time held. The loan is the amplifier, and the finding underneath it is usually a missing time dimension.
The remediation notes in these reports are worth reading as a set, because the fixes converge: measure over time, snapshot before the transaction, or make the profitable path cost more than it returns.
What reviewers look for
- Any calculation that uses a balance sampled in the same transaction it can be changed
- Governance or reward weight counted at the current block instead of a snapshot
- Collateral valuation and liquidation happening within one atomic call
- Fee or bonus curves that scale with size without an upper bound
- Invariant checks performed before, but not after, external interaction
Curated highlights
The largest disclosed payouts in this group, with our own summary of each. Every report links back to the original disclosure.
Flash-loanable veToken balance inflates emissions gauge weights
A design flaw in the gauge voting system allowed real-time veToken balance checks instead of utilizing checkpointed block or epoch snapshots. An attacker could execute a flash loan to acquire governance tokens, temporarily lock them to generate veToken voting power, vote to direct reward emissions toward their target gauge, and release the lock to repay the flash loan within the same block. This enabled uncollateralized, risk-free manipulation of protocol reward distributions.
PoolTogether: A malicious user can steal other user's deposits from Vault.sol
A critical vulnerability in PoolTogether's Vault contract allowed attackers to steal funds by exploiting unsafe integer type casting. During withdrawals, the contract calculated asset transfers using a uint256 share value but incorrectly downcasted the share amount to a uint96 for the burning process. This truncation permitted users to withdraw large amounts of assets without fully burning their corresponding share balance, effectively allowing them to drain other users' deposits by redeeming the 'remainder' shares.
LoopFi: `PositionAction.sol#onCreditFlashLoan` may end up with stuck funds for `EXACT_IN` primary swaps
LoopFi's PositionAction.onCreditFlashLoan, during a decreaseLever action, executes a primary swap from collateral to debt tokens of type EXACT_IN, meaning all withdrawn collateral is swapped. The swap output is split between repaying the flash loan (and fee) and repaying debt in the CDPVault. Because CDPVault.modifyCollateralAndDebt caps any repayment at the position's remaining debt, when the withdrawn collateral (which can be topped up by exiting ERC4626 or Balancer positions) is worth more than the remaining debt, the excess debt tokens end up stranded inside PositionAction with no path for the user to recover them. This is a loss-of-value scenario for the user rather than a third-party exploit.
NOYA: A Vault can steal all funds from another Vault through the Registry's flash loan contract due to insufficient access control in `Connector.sendTokensToTrustedAddress()`
NOYA's `BaseConnector.sendTokensToTrustedAddress()` authorizes any caller whose address equals the Registry's shared `BalancerFlashLoan` contract, without verifying which Vault (or its keeper) initiated the flash loan. Since the flash-loan callback can direct calls to arbitrary destination connectors of other Vaults, the keeper of one Vault can craft a `makeFlashLoan()` call whose callback drains another Vault's connector into the attacker's connector, then repay the flash-loan principal and keep the stolen tokens. The write-up provides a full attack path across two Vaults and a Foundry PoC, and NOYA confirmed the issue and fixed it in two commits.
LoopFi: Invalid handling of flash loan fees in `PositionAction::onCreditFlashLoan`, forcing it to always revert
LoopFi's credit flash loan flow permanently reverts whenever the flash lender charges a nonzero fee. A prior fix corrected approval amounts to include fees, but it missed that the constant amount forwarded by the lender is fully consumed repaying the position's debt, leaving nothing to cover the fee the lender requests on return. As a result, PositionAction::onCreditFlashLoan always reverts with "ERC20: transfer amount exceeds balance", breaking the decreaseLever functionality and bricking the system's fee-paying mode.
LoopFi: `decreaseLever` uses incorrect position address when withdrawing
LoopFi's `decreaseLever` function permanently breaks for `Position4626`-associated vaults because `_onDecreaseLever` withdraws collateral from the implementation contract's own address (`address(this)`) rather than from the user's `leverParams.position`. Since the collateral is actually held in the position, the withdrawal always reverts during the credit flash loan callback. The Code4rena judge upgraded the finding to High severity and the LoopFi team confirmed the bug. Fixing the function to withdraw from `leverParams.position` restores the deleveraging functionality.
All reports in this group
- LoopFi: Invalid handling of risdual amount in `PositionAction::onCreditFlashLoan`, forcing it to revertFlash loan attack$0
- Plaza Finance: Malicious user can leverage flash loans to claim all coupon rewardsFlash loan attack$0
- Ramses Exchange: The fee for the protocol in the function `RamsesV3Pool::flash()` is not calculated correctlyFlash loan attack$0
- Debita Finance V3: An attacker can steal the entire borrow and lending incentive of an epoch with FLASHLOAN in a single transactionFlash loan attack$0
- Olas: Changing VoteWeighting contract can result in lost staking incentivesFlash loan attack$0
- BadgerDAO: Staking ETH incorrectly assumes revert bubblingFlash loan attack$0
- BakerFi: When harvesting a strategy and adjusting the debt, all the leftover collateral that is not used to swap the withdrawn collateral from Aave for WETH to repay the flashloan will be locked and lost in the Strategy contractFlash loan attack$0
- BakerFi: Vault is vulnerable to first depositor inflation attackFlash loan attack$0
- BakerFi: `StrategyLeverage.harvest` doesn't account flashloan feeFlash loan attack$0
- BakerFi: `BalancerFlashLender#receiveFlashLoan` does not validate the `originalCallData`Flash loan attack$0
- DYAD: Inability to perform partial liquidations allows huge positions to accrue bad debt in the systemFlash loan attack$0
- DYAD: Attacker can frontrun user's withdrawals to make them revert without costsFlash loan attack$0
- Revert Lend: Due to interest rates update method, Interest-Free Loans are possible and the costs of DoS are reducedFlash loan attack$0
- Napier Finance - LST/LRT Integrations: Incorrect checking in `receiveFlashLoan` can cause `swapETHForYt` to fail unexpectedly.Flash loan attack$0
- Teller Finance: `FlashRolloverLoan_G5` will not work for certain tokens due to not setting the approval to `0` after repaying a loanFlash loan attack$0
- Zivoe: ZivoeYDL::distributeYield yield distribution is flash-loan manipulatableFlash loan attack$0
- Amphora Protocol: Rounding error in `WUSDA` can result in loss of user funds, especially when manipulated by an attackerFlash loan attack$0
- Spectra: All yield generated in the IBT vault can be drained by performing a vault deflation attack using the flash loan functionality of the Principal Token contractFlash loan attack$0
- WagmiLeverage V2: When the amout of token acquired by a flash loan exceeds the expected value, the callback function will fail.Flash loan attack$0
- Origami: Adversary can block any `exit` due to `preCheck` reached `cap` by using flash-loan Flash loan attack$0
- Ethereum Credit Guild: Malicious borrower can decrease Guild holders rewardFlash loan attack$0
- Olas: LP rewards in `liquidity_lockbox` can be arbitragedFlash loan attack$0
- PartyDAO: The 51% majority can hijack the party's precious tokens through an arbitrary call proposal if the `AddPartyCardsAuthority` contract is added as an authority in the party.Flash loan attack$0
- Tapioca DAO: Attacker can specify any `receiver` in `USD0.flashLoan()` to drain `receiver` balanceFlash loan attack$0
- Maia DAO Ecosystem: A malicious user can front-run Gauges's call `addBribeFlywheel` to steal bribe rewardsFlash loan attack$0
- Lybra Finance: There is a vulnerability in the `executeFlashloan` function of the `PeUSDMainnet` contract. Hackers can use this vulnerability to burn other people's eUSD token balance without permissionFlash loan attack$0