# Unistreet Launchpad: arbitrary call injection drains V4 LP positions

Unistreet LaunchpadFactoryAuto forwarded unvalidated modifyCalldata into V4 PositionManager as itself, letting attacker setApprovalForAll and burn factory-custodied LP positions for ~$17.75K.

- Payout: Real-world hack
- Severity: high
- Program: UnistreetLaunchpad
- Credited: DeFiHackLabs
- Disclosed: 2026-08-06
- Write-up quality: 8/10
- Original: https://github.com/SunWeb3Sec/DeFiHackLabs/blob/main/src/test/2026-08/UnistreetLaunchpad_exp.sol
- Library page: https://bugbountylibrary.com/r/dhl%3A20260806-unistreetlaunchpad
- Tags: domain:web3 impact:funds-loss kind:incident platform:defihacklabs sev:high tech:evm tech:solidity technique:chained technique:source-review vuln:access-control vuln:business-logic

**Target:** LaunchpadFactoryAuto launch() forwarding to Uniswap V4 PositionManager multicall
**Root cause:** launch() is permissionless and forwards caller-supplied initCalldata/modifyCalldata verbatim into PositionManager.multicall executed as the factory, which owns all launch LP NFTs. No validation on forwarded calldata content.
**Steps:**
1. Call `FACTORY.launch(p, initCalldata, modifyCalldata, sb)` with `initCalldata = initializePool(CPOC/WETH key, sqrtPriceX96=2^96)` and `modifyCalldata = abi.encodeWithSelector(setApprovalForAll.selector, attacker, true)`
2. Factory calls `POSITION_MANAGER.multicall([initCalldata, modifyCalldata])` with msg.sender = factory, granting attacker operator rights over all factory-owned position NFTs
3. For each victim tokenId call `POSM.modifyLiquidities(abi.encode(actions=[0x03 BURN_POSITION, 0x11 TAKE_PAIR], params), deadline)` with TAKE_PAIR recipient = attacker contract
4. Transfer swept USDC and WETH to attacker EOA
**How found:** Code reading of launch(): it builds `calls[0]=initCalldata; calls[1]=modifyCalldata` and passes them to `IPositionManager.multicall` with msg.sender preserved as the factory — the factory is ERC721 owner of all launch positions, so any calldata runs with its authority.
**Exploitation:** Single permissionless tx: launch a throwaway CPOC token to smuggle setApprovalForAll(attacker,true) through the factory's multicall, then as operator burn each of the 7 factory-custodied V4 positions and TAKE_PAIR both currencies to the attacker, forwarding ~17,743.91 USDC + 0.0072 WETH to the EOA.
**Escalation:** One injected approval grants operator over every position the factory custodies, so a single launch drains all launches' LP, not just the attacker's.
**Insight:** When a contract forwards user calldata into a multicall/delegatecall target while holding privileged ownership (ERC721 LP NFTs, approvals), the forwarded selector is attacker-controlled — check whether setApprovalForAll/transferFrom can be smuggled through the same entrypoint that legitimately calls initializePool/modifyLiquidities.
