# Anybody can buy collateral on behalf of other users without having any allowance using the multiHopBuyCollateral()

SGLLeverage.multiHopBuyCollateral only checks allowance for collateralAmount, not borrowAmount, letting anyone force a borrow onto a victim's account.

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

**Target:** SGLLeverage.multiHopBuyCollateral (Singularity market leverage module)
**Root cause:** multiHopBuyCollateral validates allowance only for the collateralShare derived from collateralAmount, but never calls _allowedBorrow on the borrowShare produced by _borrow, so the borrowAmount debt is taken on behalf of `from` without any allowance.
**Steps:**
1. Set up SGL market with a victim (`deployer`) holding collateral and no borrow.
2. Attacker (`eoa1`) calls `SGL_10.multiHopBuyCollateral(deployer.address, 0, bigDummyAmount, swapData, lzData, externalData)` with `collateralAmount=0` to skip the allowance check.
3. Because collateralAmount is 0, `_allowedBorrow(from, collateralShare)` passes trivially.
4. `_borrow(from, from, borrowAmount)` executes, crediting debt to the victim's borrowPart.
5. Verify `SGL_10.userBorrowPart(deployer)` > 0 and collateral share increased, with attacker having no allowance.
**How found:** Code reading of multiHopBuyCollateral: noticed the allowance check only covers collateralShare from collateralAmount, while borrowShare from _borrow is never validated against the caller's allowance.
**Exploitation:** Attacker calls multiHopBuyCollateral with collateralAmount=0 and borrowAmount set to the maximum the victim can borrow while staying solvent; the borrow is credited to the victim's account and the borrowed USDO is sent cross-chain via sendForLeverage to the attacker-controlled swap path, leaving the victim with debt.
**Insight:** In leverage/multihop functions that take both a collateral and a borrow parameter, check every allowance-gated side effect separately; setting one parameter to zero can bypass a check that only guards the other.
