# The direct redeem fee can be circumvented

NFTX vault redeem picks a random NFT in the same tx, so a user can revert unless they get the desired token, dodging the direct redeem fee.

- Payout: Audit contest
- Severity: medium
- Program: NFTX
- Disclosed: 2021-06-21
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2021-05-nftx-findings/issues/71
- Library page: https://bugbountylibrary.com/r/c4%3A2021-05-nftx%3AM-09
- Tags: area:web3 domain:web3 impact:funds-loss kind:contest platform:code4rena sev:medium tech:evm tech:solidity technique:race-window vuln:accounting-error vuln:business-logic

**Target:** NFTXVaultUpgradeable.sol redeem() random token selection
**Root cause:** The random NFT for a redeem is chosen inside the same transaction via getRandomTokenIdFromFund(), so the caller can inspect the result and revert if it isn't the token they want, paying no fee.
**Steps:**
1. Call `vault.redeem(1,[])` which returns `resultID` from `getRandomTokenIdFromFund()` (line 374).
2. Wrap in a contract that `require(resultID[0] == targetTokenID)` and reverts otherwise.
3. Submit via Flashbots `FlashbotsCheckAndSend` so reverted txs are never published/charged.
4. Repeat each block or after nonce update from `getPseudoRand()` until the desired token is drawn, avoiding `directRedeemFee`.
**How found:** Noticed that random token selection happens in the same transaction as payment/swap, making the outcome observable and revertible before settlement.
**Exploitation:** Attacker repeatedly submits redeem transactions through Flashbots bundles that revert unless the random draw equals the target token; reverting bundles cost nothing and are not broadcast, so the attacker obtains the specific NFT without paying the direct redeem fee, reducing protocol/user fee earnings.
**Insight:** When randomness is drawn in the same tx as value transfer, the caller can conditionally revert; look for getRandom/rand calls adjacent to payment logic and check whether Flashbots-style private bundles make reverts free.

