# Attacker can specify any receiver in USD0.flashLoan() to drain receiver balance

USD0.flashLoan() lets caller pick any receiver; the contract burns amount+fee from receiver's balance using receiver's allowance to the contract, draining victims.

- Payout: Contest reward
- Severity: high
- Program: Tapioca DAO
- Credited: mojito\_auditor
- Disclosed: 2023-11-16
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2023-07-tapioca-findings/issues/1223
- Library page: https://bugbountylibrary.com/r/c4%3A2023-07-tapioca%3AH-15
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:high tech:solidity technique:source-review vuln:access-control vuln:business-logic

**Target:** USD0 token flashLoan() function
**Root cause:** flashLoan() mints to and burns from a caller-supplied receiver without validating that the caller is authorized by the receiver; the allowance check is against address(this) rather than msg.sender.
**Steps:**
1. Attacker calls `USD0.flashLoan(receiver=victim, amount, ...)` where victim has an outstanding allowance to the USD0 contract.
2. Contract mints `amount` to victim, invokes callback on attacker.
3. On repayment, contract checks `allowance(victim, address(this)) >= amount + fee` and decrements it.
4. Contract calls `_burn(victim, amount + fee)`, consuming victim's balance to cover the fee/principal.
**How found:** Code review of the flashLoan repayment path: noticed receiver is caller-controlled and the allowance/burn target is the receiver, not msg.sender.
**Exploitation:** Attacker repeatedly invokes flashLoan with a victim address that has approved the USD0 contract; each call burns amount+fee from the victim, transferring value to the attacker via the minted loan.
**Insight:** In flash-loan/mint-burn designs, check who is authorized to move the receiver's funds: allowance should be from receiver to msg.sender, not to the token contract itself.
