# Floor Protocol: extMulticall drains victim NFTs via arbitrary transferFrom

Floor Protocol's extMulticall proxy executed arbitrary safeTransferFrom calls on behalf of any owner, letting an attacker drain a victim's Pudgy Penguins NFTs worth ~$1.6M.

- Payout: Real-world hack
- Severity: critical
- Program: FloorProtocol
- Analysis by: DeFiHackLabs
- Disclosed: 2023-12-17
- Write-up quality: 6/10
- Original: https://github.com/SunWeb3Sec/DeFiHackLabs/blob/main/src/test/2023-12/FloorProtocol_exp.sol
- Library page: https://bugbountylibrary.com/r/dhl%3A20231217-floorprotocol
- Tags: area:web3 domain:web3 impact:funds-loss impact:integrity kind:incident platform:defihacklabs sev:critical tech:evm tech:solidity technique:source-review vuln:access-control vuln:business-logic

**Target:** ERC1967 proxy extMulticall batch-call function on NFT derivative protocol
**Root cause:** The extMulticall function on the ERC1967 proxy executed arbitrary CallData (target + calldata) without verifying the caller was authorized to act on the referenced tokens, so an attacker could invoke safeTransferFrom(victim, attacker, tokenId) for any NFT.
**Steps:**
1. Fork mainnet at block 18802287.
2. Enumerate victim 0xe5442aE87E0fEf3F7cc43E507adF786c311a0529's PPG (0xBd3531dA5CF5857e7CfAA92426877b022e612cf8) tokens via tokenOfOwnerByIndex.
3. Build CallData[] where each entry targets PPG with `safeTransferFrom(victim, attacker, tokenId)`.
4. Call `extMulticall(calls)` on proxy 0x49AD262C49C7aA708Cc2DF262eD53B64A17Dd5EE.
5. Implement onERC721Received to accept the NFTs; victim balance drops to 0.
**How found:** Public analysis attributes the flaw to a bad contract upgrade days earlier that introduced the vulnerable extMulticall path; the researcher (0xfoobar) identified the unauthenticated arbitrary-call primitive in the upgraded proxy.
**Exploitation:** Attacker batched one safeTransferFrom per victim-owned Pudgy Penguin NFT into a single extMulticall invocation on the upgraded proxy; the proxy executed each call without checking the caller's authority over the tokens, transferring all victim NFTs to the attacker in one transaction.
**Escalation:** Batched all of the victim's NFTs into a single multicall for atomic mass theft; repeated across multiple attack txs.
**Insight:** When a proxy exposes a batch/multicall that forwards arbitrary target+calldata, check whether it enforces per-call authorization (msg.sender ownership/approval) — an upgrade adding such a helper can turn any token's transferFrom into a public primitive.
