# Size FlashLoanLooping: arbitrary call drains victim's token allowance

Size FlashLoanLoopingV1_7's generic route swap allowed arbitrary external calls, letting an attacker use a victim's Pendle PT allowance to steal 540k PT tokens.

- Payout: Real-world hack
- Severity: high
- Program: SizeFlashLoanLooping
- Credited: DeFiHackLabs
- Disclosed: 2025-08-15
- Write-up quality: 7/10
- Original: https://github.com/SunWeb3Sec/DeFiHackLabs/blob/main/src/test/2025-08/SizeFlashLoanLooping_exp.sol
- Library page: https://bugbountylibrary.com/r/dhl%3A20250815-sizeflashloanlooping
- Tags: domain:web3 impact:funds-loss kind:incident platform:defihacklabs sev:high tech:evm tech:solidity technique:source-review vuln:access-control vuln:business-logic

**Target:** FlashLoanLoopingV1_7 contract on Ethereum
**Root cause:** DexSwap._swapGenericRoute() accepts caller-controlled router and calldata, approves tokenIn to that router, then performs router.call(data). Exposed via public loopPositionWithFlashLoan, this enables arbitrary external calls that can spend any token allowances granted to the vulnerable contract.
**Steps:**
1. Attacker deploys attack contract and funds with 10,000 wei WETH dust.
2. Attack contract wraps dust to WETH via `IWETH.deposit`.
3. Constructs `GenericRouteParams` with `router=PENDLE_PT`, `tokenIn=WETH`, `data=abi.encodeWithSelector(IERC20.transferFrom.selector, VICTIM, address(this), PT_AMOUNT)`.
4. Builds `LoopParamsV17` with `swapParamsArray` containing one `SwapParams` of method `GenericRoute` and the encoded route, empty sell credit params, `flashLoanAmountBorrowToken=0`, `targetLeveragePercent=10000`.
5. Calls `IFlashLoanLoopingV17(FLASH_LOAN_LOOPING).loopPositionWithFlashLoan(loopParams)`.
6. The contract approves WETH to the router (Pendle PT) and calls `router.call(data)`, executing `transferFrom(VICTIM, attacker, PT_AMOUNT)` using the victim's allowance to the vulnerable contract.
7. Attacker receives 540,576,557,356,106,541,792 PT tokens.
**How found:** Likely identified that the public loopPositionWithFlashLoan function accepts arbitrary SwapParams including GenericRoute, and that _swapGenericRoute performs an external call to a caller-supplied router after approving tokenIn. Recognized that any token allowance to the vulnerable contract could be abused by setting the router to the token contract and calldata to transferFrom.
**Exploitation:** Attacker used a minimal WETH dust deposit to trigger the flashloan loop entrypoint with a malicious generic route. The vulnerable contract approved WETH to the attacker-specified router (Pendle PT token contract) and then called it with attacker-controlled calldata, which executed a transferFrom pulling the victim's PT tokens (for which the victim had granted allowance to the vulnerable contract) to the attacker.
**Insight:** When a contract exposes a generic external call primitive (arbitrary router + calldata) and holds token approvals from users, check if the call target can be a token contract to invoke transferFrom and drain allowances. Public entrypoints that pass user-controlled swap data into such primitives are prime targets.
