# It's possible to swap NFT token ids without fee and also attacker can wrap unwrap all the NFT token balance of the Pair contract and steal their air drops for those token ids

Caviar Pair.wrap/unwrap are fungible over tokenIds, letting an attacker cycle all pooled NFTs to claim their airdrops and bypass swap fees.

- Payout: Contest reward
- Severity: medium
- Program: Caviar
- Credited: unforgiven
- Disclosed: 2023-01-26
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2022-12-caviar-findings/issues/367
- Library page: https://bugbountylibrary.com/r/c4%3A2022-12-caviar%3AM-04
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:medium tech:evm tech:solidity technique:source-review vuln:accounting-error vuln:business-logic vuln:fee-bypass

**Target:** Pair.sol wrap()/unwrap() NFT fractionalization contract
**Root cause:** wrap() mints 1e18 per tokenId and unwrap() burns 1e18 per tokenId with no binding between depositor and specific tokenId, so any whitelisted id can be redeemed for any other.
**Steps:**
1. Attacker buys one whitelisted NFT (attackerID1) and calls `wrap([attackerID1], proofs)` to receive `1e18` fractional tokens.
2. Loop over every tokenId i held by the Pair contract: call `unwrap([i])` (burns `1e18`), call `nft.getAirDrop(i)` to claim the airdrop, then `wrap([i], proofs)` to recover `1e18`.
3. After the loop, `unwrap([attackerID1])` to recover the original NFT.
4. All airdrops for pooled tokenIds are captured in a single transaction.
**How found:** Code reading of wrap/unwrap: noticed mint/burn is per-tokenId count with no mapping of depositor to id, so ids are interchangeable; reasoned that temporary ownership during unwrap enables calling holder-gated functions like airdrop claims.
**Exploitation:** Attacker contract holds 1e18 fractional tokens as a reusable key; each unwrap/wrap cycle temporarily owns a pooled NFT long enough to call its airdrop/staking-claim function, then returns it. Net cost is gas only; all airdrops belonging to fractional owners are stolen.
**Escalation:** Same primitive also enables fee-free NFT id swaps (no swap fee accrues to LPs) and theft of per-NFT staking rewards or any owner-gated action on pooled NFTs.
**Insight:** When a vault mints fungible shares per deposited NFT id but redeems by arbitrary id, any holder-gated side effect (airdrops, staking claims, owner-only calls) on pooled ids becomes harvestable by cycling one share through unwrap/wrap.
