# buyAndSwap1155WETH() function may cause loss of user assets

NFTXMarketplaceZap.buyAndSwap1155WETH passes msg.value (0) instead of maxWethIn to _buyVaultToken, breaking swaps and locking user ETH in the contract.

- Payout: Audit contest
- Severity: high
- Program: NFTX
- Found by: cccz
- Disclosed: 2022-03-24
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2021-12-nftx-findings/issues/2
- Library page: https://bugbountylibrary.com/r/c4%3A2021-12-nftx%3AH-01
- Tags: area:web3 domain:web3 impact:funds-loss kind:contest platform:code4rena sev:high tech:evm tech:solidity technique:source-review vuln:business-logic

**Target:** NFTXMarketplaceZap.sol buyAndSwap1155WETH / _buyVaultToken
**Root cause:** buyAndSwap1155WETH pulls maxWethIn WETH via transferFrom but calls _buyVaultToken with msg.value, which is 0 for a WETH-funded call, so the swap either reverts or leaves ETH stranded.
**Steps:**
1. User approves WETH and calls `buyAndSwap1155WETH(vaultId, idsIn, amounts, specificIds, maxWethIn, path, to)` with `msg.value=0`.
2. Contract does `WETH.transferFrom(msg.sender, address(this), maxWethIn)` pulling WETH.
3. Contract calls `_buyVaultToken(address(vault), redeemFees, msg.value, path)` — maxWethIn arg is 0.
4. `sushiRouter.swapTokensForExactTokens(redeemFees, 0, ...)` fails; if user also sent ETH, it stays locked in contract.
**How found:** Code review of the payable zap function comparing the transferFrom amount (maxWethIn) against the argument actually forwarded to _buyVaultToken (msg.value).
**Exploitation:** User mistakenly calls buyAndSwap1155WETH with both ETH and pre-approved WETH; the swap uses msg.value=0, so the call reverts or ETH remains trapped in the zap contract with no refund path.
**Insight:** In payable zap/multicall wrappers, audit every internal call's amount argument against the token actually pulled — mixing msg.value and an explicit maxIn parameter is a recurring source of stuck funds and broken swaps.
