# Can mint NFT with the desired attributes by reverting transaction

AI Arena FighterFarm derives NFT attributes from DNA in the same mint transaction, so a contract wallet can revert onERC721Received until it rolls desired attributes.

- Payout: Contest reward
- Severity: medium
- Program: AI Arena
- Credited: klau5
- Disclosed: 2024-05-14
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2024-02-ai-arena-findings/issues/376
- Library page: https://bugbountylibrary.com/r/c4%3A2024-02-ai-arena%3AM-05
- Tags: domain:web3 impact:integrity kind:contest platform:code4rena sev:medium tech:evm tech:solidity technique:race-window vuln:business-logic

**Target:** FighterFarm.claimFighters / _createNewFighter NFT minting
**Root cause:** Physical attributes (element, weight, DNA) are computed and assigned inside the same transaction that mints the NFT, so the recipient's onERC721Received callback can revert and force a retry until favorable randomness lands.
**Steps:**
1. Deploy a contract wallet implementing onERC721Received that reads getAllFighterInfo(tokenId) and reverts unless weight == 95.
2. Obtain a valid claim signature for the contract wallet address via the delegated signer.
3. Call `fighterFarm.claimFighters(numToMint, claimSignature, claimModelHashes, claimModelTypes)` from the contract wallet inside a try/catch.
4. On revert, retry; interleave other mints (`_mintFromMergingPool`) to shift fighters.length and thus the DNA/attributes.
5. Repeat until the minted fighter has the desired weight/attributes.
**How found:** Noticed attributes are set in the same transaction as the mint and that _safeMint invokes onERC721Received on the recipient, giving the recipient a revert hook to reroll randomness.
**Exploitation:** Attacker uses a contract wallet whose onERC721Received reverts when attributes are undesirable; the whole claim reverts and can be retried at will, letting them cherry-pick rare/optimal fighters without paying extra beyond gas.
**Insight:** Any randomness committed in the same tx as an ERC721 _safeMint is rerollable by a contract recipient reverting in onERC721Received; look for attribute assignment co-located with minting.
