# Unverified670471: unchecked flash loan callback drains funds

Unverified proxy accepted forwarded Balancer flash loan callback, letting attacker keep borrowed WETH/WBTC/USDC while victim repaid Balancer.

- Payout: Real-world hack
- Severity: high
- Program: Unverified670471
- Credited: DeFiHackLabs
- Disclosed: 2025-07-26
- Write-up quality: 7/10
- Original: https://github.com/SunWeb3Sec/DeFiHackLabs/blob/main/src/test/2025-07/Unverified670471_exp.sol
- Library page: https://bugbountylibrary.com/r/dhl%3A20250726-unverified670471
- Tags: domain:web3 impact:funds-loss kind:incident platform:defihacklabs sev:high technique:chained vuln:access-control vuln:flash-loan

**Target:** Ethereum smart contract proxy
**Root cause:** The unverified proxy accepted an externally forwarded Balancer receiveFlashLoan callback without sufficient caller/origin validation, allowing an attacker to trigger the victim's callback logic and have the victim repay the flash loan.
**Steps:**
1. Attacker calls Balancer Vault `flashLoan` for WETH, WBTC, USDC with recipient = attack contract.
2. Balancer calls attack contract's `receiveFlashLoan`.
3. Attack contract forwards the callback to victim: `I BalancerFlashLoanRecipient(VICTIM).receiveFlashLoan(tokens, amounts, feeAmounts, userData)`.
4. Victim processes the callback and repays Balancer (or otherwise releases funds), while attack contract retains the borrowed assets.
5. Repeat for each token; swap WBTC and USDC to WETH via Uniswap V2; withdraw WETH to ETH; send bribe and profit.
**How found:** Likely identified that the unverified proxy lacked caller validation on the Balancer `receiveFlashLoan` callback, allowing an attacker to invoke it externally and force the victim to repay a flash loan.
**Exploitation:** Attacker used Balancer flash loans to borrow WETH, WBTC, and USDC. By forwarding the Balancer callback to the vulnerable victim contract, the victim repaid the flash loans while the attacker kept the borrowed assets. Attacker swapped WBTC and USDC to WETH, withdrew to ETH, paid a bribe, and kept ~0.485 ETH profit.
**Insight:** When a contract implements a flash loan callback, verify that it validates both the caller (the lender) and the initiator/origin of the loan; otherwise anyone can trigger the callback and make the contract repay loans it did not initiate.
