LoopFi — disclosed vulnerability reports and payouts
Every publicly disclosed and closed bug bounty report we hold for LoopFi, with our own summary of each finding and a link to the original disclosure.
- Reports indexed
- 51
- Total paid
- $0
- Critical
- 0
- Largest payout
- $0
This page collects the 51 closed, publicly disclosed LoopFi reports indexed on CoinBuggie. Nothing here is active or unpatched — every entry was published by the programme or the researcher after remediation.
The findings concentrate in Logic error, Flash loan attack, Access control, Reentrancy, Integer overflow / underflow, across EVM-Solidity. Reading a single protocol end to end is the fastest way to see which assumptions its codebase repeatedly gets wrong, which is usually a better predictor of where the next finding lives than the category alone.
Use the vulnerability class links below to compare these findings against the same bug class in other protocols.
What reviewers look for
- Logic error findings disclosed against LoopFi
- Flash loan attack findings disclosed against LoopFi
- Access control findings disclosed against LoopFi
- Reentrancy findings disclosed against LoopFi
- Integer overflow / underflow findings disclosed against LoopFi
Curated highlights
The largest disclosed payouts in this group, with our own summary of each. Every report links back to the original disclosure.
LoopFi: Debt position interest is compounded while pool interest is simple causing inconsistency between `expectedLiquidity_` and `availableLiquidity_`
LoopFi's lending protocol derives debt interest through two divergent calculation paths: PoolV3 records base interest as simple linear growth on total borrowed principal, while the per-position debt in the CDP vault is computed from an interestIndex that is re-multiplied by the same linear growth factor on every update. Because the index compounds with each invocation while the pool interest does not, the vault's accrued interest eventually exceeds the pool's recorded interest, breaking the expectedLiquidity_/availableLiquidity_ invariant. The divergence makes borrowers pay more interest than required and can lower effective borrowing rates; when shares backed by the surplus interest are withdrawn, _updateBaseInterest underflows expectedLiquidity and the final withdrawal reverts, locking user funds. The recommended fix aligns the index update with the pool's simple-interest accumulation.
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.
LoopFi: Liquidation doesn't account for penalty when calculating collateral to give, allowing users to profit by borrowing and self-liquidating
LoopFi's CDPVault lets users borrow WETH from PoolV3 by posting collateral, and liquidates unsafe positions at a discounted price. To deter profitable self-liquidation, liquidatePosition is meant to subtract a liquidation penalty from the amount a liquidator repays, sending that penalty to the treasury as protocol profit. The bug is that the collateral handed to the liquidator (takeCollateral) is computed from the full repayAmount rather than repayAmount minus the penalty. As a result, a user who borrows, lets interest push their position unsafe, and then liquidates their own position only repays repayAmount minus penalty against debt while receiving the full discounted collateral — making the penalty redundant and turning self-liquidation into direct profit drained from lenders and the protocol.
LoopFi: Usage of `lastEligibleStatus` can cause user to miss out on rewards on `manualStopEmissionsFor` invocation
LoopFi's emission-eligibility flow contains a state-assumption bug: the `handleActionAfter` path optimistically skips refreshing a user's full registered balance when the user is both eligible now and was eligible before, assuming all vault balances are already current. That assumption is broken by the whitelisted operator function `manualStopEmissionsFor`, which zeroes `user.amount` and `user.rewardDebt` for each supplied vault. After such a call, if the user performs a position update that makes them eligible in one vault, only that vault's balance is updated and the remaining vaults stay zeroed, so the user stops accruing emission rewards on them. The LoopFi maintainer confirmed the finding and recommended removing the `lastEligibleStatus` optimization or reconciling it with the manual-stop flow.
LoopFi: Bug in `claim` allows users who are disqualified to claim their previously earned emissions
LoopFi's ChefIncentivesController evaluates a locker's reward eligibility before refreshing their eligibility status against current collateral prices inside claim. Because the price-sensitive refresh runs only after the gate check, a user whose total value locked has fallen below the required 5% of debt can still pass the stale check and collect previously earned emissions they are no longer entitled to. The judge confirmed the flaw and rated it Medium. The correct fix reorders the two calls so the refresh precedes the eligibility check, forcing a revert for newly ineligible users.
LoopFi: Directly sending dust token amount will slow down distribution in `MultiFeeDistribution.sol`
LoopFi's MultiFeeDistribution contract derives its reward emission rate from any unexpected balance delta of the reward token. A public path such as getReward calls _notifyUnseenReward, which computes balanceOf(this) minus the tracked r.balance and, when positive, folds the entire delta into _notifyReward, recomputing rewardPerSecond and pushing periodFinish out by a full rewardsDuration. An attacker can transfer a dust amount directly to the contract and then trigger getReward, collapsing the per-second rate to a much lower flat value and locking legitimate stakers' rewards into a fresh, longer distribution window. Repeating the cycle compounds the slowdown; a Foundry PoC shows daily rewards dropping from about 3.33e18 to under 1e18 after a single wei-level send and to roughly 0.33e18 after twenty iterations, all at trivial attacker cost. LoopFi confirmed the issue, though the judge classified the severity as Medium rather than the reported High.
All reports in this group
- LoopFi: An infinite loop in `MultiFeeDistribution.sol` withdrawLogic error$0
- LoopFi: DOS attack to `SwapAction.transferAndSwap()` when using an ERC20 permit `transferFrom`Logic error$0
- LoopFi: Because of the asset: `Share 1:1 Conversion`, if vault incurs a loss, the last user to withdraw will take the entire lossLogic error$0
- LoopFi: `AuraVault::claim` reward calculation does not deduct fees from reward amount, causing DoS or extra rewards lostLogic error$0
- LoopFi: Users of a vault can steal other user's rewards when one vault's `lastRewardTime` differs from another vault's `lastRewardTime`Logic error$0
- LoopFi: Emission schedule is not followed and can cause unexpected allocation of rewardsLogic error$0
- LoopFi: `PositionAction.decreaseLever()` fails to consider the loan fee in Flashlender when calculating `loanAmount`, as a result, the functionality will not work when `protocolFee != 0`Logic error$0
- LoopFi: `SwapAction.sol#balancerSwap` does not support native ETH as input tokenLogic error$0
- LoopFi: Malicious actor can abuse the minimum shares check in `StakingLPEth` and cause DoS or locked funds for the last user that withdrawsLogic error$0
- LoopFi: Unclaimed rewards handling issue in `AuraVault` contract functions (`AuraVault::deposit`, `AuraVault::mint`, `AuraVault::withdraw` and `AuraVault::redeem`)Logic error$0
- LoopFi: Lack of slippage check while interacting with ERC4626 Vault in `PositionAction4626` could lead to users' fund lossLogic error$0
- LoopFi: `INFLATION_PROTECTION_TIME` can not be up to a year as intended because it is hardcoded to `1749120350`Logic error$0
- LoopFi: `vestTokens` bug in `MultiFeeDistribution.sol` causes new incentives to erase previous incentivesLogic error$0
- LoopFi: `PositionAction.sol#_deposit` incorrectly checks `auxSwap.assetIn` should be equal to `collateralParams.targetToken`Logic error$0
- LoopFi: Honest users could be permanently DOS'd from withdrawing their vested tokens/rewardsAccess control$0
- LoopFi: Invalid handling of flash loan fees in `PositionAction::onCreditFlashLoan`, forcing it to always revertFlash loan attack$0
- LoopFi: `PositionAction4626::increaseLever` will always revertLogic error$0
- LoopFi: Zero rates on new quoted tokens allow an attacker to take an interest free quotaLogic error$0
- LoopFi: Malicious borrower cycle exploits to inflate interest ratesLogic error$0
- LoopFi: `decreaseLever` uses incorrect position address when withdrawingFlash loan attack$0
- LoopFi: `CDPVault.sol#liquidatePositionBadDebt()` doesn't correctly handle profit and lossLogic error$0
- LoopFi: In `PositionActionPendle::_onDecreaseLever`, `tokenOut` is implemented incorrectlyLogic error$0
- LoopFi: Invalid handling of risdual amount in `PositionAction::onCreditFlashLoan`, forcing it to revertFlash loan attack$0
- LoopFi: `PositionAction4626::_onDecreaseLever` wrongly updates `tokenOut` forcing user's funds to be stuck in the position action contractLogic error$0
- LoopFi: `PositionAction20._onWithdraw` and `PositionPendle20._onWithdraw` also returns token amount in wrong scaleLogic error$0
- LoopFi: Bringing a position from unsafe to safe by liquidation partiallyLogic error$0
- LoopFi: It is nearly impossble for Liquidators to use `liquidatePosition()` to fully pay off a non bad-debt positionLogic error$0
- LoopFi: `PoolAction::_balancerExit` returns wrong token out amountLogic error$0
- LoopFi: `CDPVault.sol#liquidatePositionBadDebt()` should not set profit `= 0` when calling `pool.repayCreditAccount()`Reentrancy$0
- LoopFi: Lack of Slippage Control in `AuraVault::deposit` and `AuraVault::mint` Functions Can Lead to Unexpected Financial Losses for UsersLogic error$0
- LoopFi: Rewards may be spread out among the wrong time period due to the way the protocol calculates itLogic error$0
- LoopFi: `WhenNotPaused` modifier in the CDPVault can be bypassed by usersAccess control$0
- LoopFi: Malicious borrower can evade full liquidation in `CDPVault::liquidatePosition` by repaying small amounts of debtLogic error$0
- LoopFi: `SwapAction::getSwapToken` will return wrong swap token for balancer `EXACT_OUT` swapsLogic error$0
- LoopFi: `CDPVault.liquidatePosition()` does not scale `takeCollateral` with `tokenScale`; therefore, it might send the wrong amount of collateral to the liquidator when `tokenScale ! = 1 ether`Logic error$0
- LoopFi: Discrepancy between the `lastRewadTime` and the `lastAllPoolUpdate` can allow for incorrect reward distribution to pools if `registerRewardDeposit` deposits less assetsLogic error$0
- LoopFi: Incorrect calculation of `newCumulativeIndex` in function `calcDecrease`Logic error$0
- LoopFi: Rewards might be lost due to the error that `_updateRewardIndex()` might advance `lastBalance` without advancing index for a tokenInteger overflow/underflow$0
- LoopFi: Wrong repayment amount used in `PositionAction::_repay`, forcing users to unexpectedly lose fundsLogic error$0
- LoopFi: `PositionAction.sol#onCreditFlashLoan` may have leftover tokens after conducting `leverParams.auxSwap`Logic error$0
- LoopFi: `Flashlender.sol#flashLoan()` should use `mintProfit()` to mint fees, as the current implementation may lead to locked up WETH in PoolV3Logic error$0
- LoopFi: Incorrect address is used as `spender` for ERC20 permit signature verificationLogic error$0
- LoopFi: `PositionActionPendle.sol#_onWithdraw` does not have slippage parameter `minOut` setLogic error$0
- LoopFi: ChefIncentivesController caches `endRewardTime`, which is not required, and may cause issues during reward updateLogic error$0
- LoopFi: Availability of deposit invariant can be bypassedFront-running / MEV$0