Submitted by fnanni and niser93 (1, 2), also found by d3e4 (1, 2, 3)
Note: the content from two separate warden reports is included here, as the judge noted: 
Lines of code:
https://github.com/ArenaX-Labs/2024-02-ai-arena-mitigation/blob/1192a55963c92fb4bd9ca8e0453c96af09731235/src/FighterFarm.sol#L366
https://github.com/ArenaX-Labs/2024-02-ai-arena-mitigation/blob/1192a55963c92fb4bd9ca8e0453c96af09731235/src/MergingPool.sol#L142-L175
https://github.com/ArenaX-Labs/2024-02-ai-arena-mitigation/blob/1192a55963c92fb4bd9ca8e0453c96af09731235/src/FighterFarm.sol#L425
https://github.com/ArenaX-Labs/2024-02-ai-arena-mitigation/blob/1192a55963c92fb4bd9ca8e0453c96af09731235/src/FighterFarm.sol#L241
Related to mitigation of: Issue 1017: Users can get benefited from DNA pseudorandomly calculation
Comments
Before, the pseudorandom derivation of new fighters DNA was vulnerable to manipulation in several ways:
Mitigation
PR #11
This issue has been only partially mitigated.
FighterFarm::redeemMintPass
Theres one instance in which the mitigation works. FighterFarm::redeemMintPass now relies on a trusted _delegatedAddress which controls what parameters are being used, including the mintPassDnas values which are keccak256 hashed into DNAs. This fix was introduced as mitigation of H-03.
FighterFarm::claimFighters
On the other hand, FighterFarm::claimFighters now relies as well on a trusted _delegatedAddress, but it signs:
and then msg.sender, nftsClaimed[msg.sender][0] and nftsClaimed[msg.sender][1] are used to generate the DNA hash. In all scenarios in which msg.sender could be manipulated, for example if promotional campaigns are run in which users could precompute and use the address resulting in the best DNA, the issue remains unmitigated. Note that nftsClaimed[msg.sender] values of newly generated addresses are always 0 and numToMint could probably be known or assumed in advance.
Another consequence of the fix that seems incorrect is that all fighters minted within a FighterFarm::claimFighters call will have the same DNA, because msg.sender, nftsClaimed[msg.sender][0] and nftsClaimed[msg.sender][1] dont change among iterations in:
Note that previously fighter.length would increase as each fighter was minted, and therefore each fighter would have a different DNA.
FighterFarm::mintFromMergingPool
FighterFarm::mintFromMergingPool now sets the new dna to uint256(keccak256(abi.encode(to, fighters.length))), making the dna dependent on the current amount of fighters and the user address. Using to is relatively safe, taking into account that winners of NFTs in the MergingPool raffle would have to play the game for probably a long time before they win, so manipulating the address in advance would require a lot of speculation on several variables they dont control.
However, users calling this function have full control regarding when to call MergingPool::claimRewards. This means that users can delay the claim till fighters.length results in a DNA they like, which can be accomplished by pre-computing the expected DNAs for all the following fighters.length values.
FighterFarm::reRoll
In this case msg.sender is no longer used for the DNA generation, but it is vulnerable since it still uses tokenId and numRerolls[tokenId]. tokenId is to some extent manipulable, because ids are incremental and users claiming new fighters have full control of when they execute the claim. Additionally, all possible re-rolling DNAs could be calculated in order to know which one will be the best one. 
With this information, players could choose to some degree the token ID of their new fighter and re-roll it up to maxRerollsAllowed times until they get their desired DNA. There could even be a front-running madness scenario for claiming new fighters with exceptionally good token IDs, since re-rolled DNAs depend on token ID and amount of re-rolls.
Suggestion
Conclusion
The mitigation does not fully solve the DNA generation issues.
Old lines of code: https://github.com/code-423n4/2024-02-ai-arena/blob/cd1a0e6d1b40168657d1aaee8223dc050e15f8cc/src/FighterFarm.sol#L324
Mitigated lines of code: https://github.com/ArenaX-Labs/2024-02-ai-arena-mitigation/blob/setUpAirdrop-mitigation/src/FighterFarm.sol#L366
Vulnerability details
The issue was reported in #578 and #1017.
The vulnerability is inside FighterFarm.mintFromMergingPool():
This function can be called only by the merging pool contract. This means that msg.sender must be _mergingPoolAddress.
However, msg.sender is also used as dna parameter of _createNewFighter() (line L324). 
Impact
Even if an attacker cant exploit this bad randomness to obtain better fighters, players could forecast the attributes of fighters that will be created in the future, due to the bad randomness caused by this issue.
Recommended Mitigation proposed by wardens
The mitigation proposal is to replace msg.sender in line L324 with the address to, that should represents the player who calls MergingPool.claimRewards():
This solution was implemented by the Ai Arena team.
Comment about the Mitigation Proposal
This finding belongs to a group of issues that reported the low randomness of dna. Two of the most important are #53 and #519. The root cause is that msg.sender can be a bad source of randomness because an attacker could create a malicious contract at the wanted address using, for example, Create2.
In the case above, before the mitigation, nobody could exploit the vulnerability, because the msg.sender value was always the _mergingPoolAddress. After the mitigation, the dna of the new fighter relies on the callers address. So, the mitigation could introduce the possibility of manipulating the msg.sender address and obtaining wanted attributes.
Attack Vector
Lets think that before the current round, fighters.length into FighterFarm.sol is 0. Eve locally tries many combinations and finds that the tuple (address_E, fighters.length=3) permits creating a very rare fighter: Eve can forecast this is because she can exploit the line FighterFarm.sol#214:
to obtain dna and then use its value to precompute the new fighters physical attributes:
Now, Eve creates a new contract at address_E and tries to win the current round (for example using a new fighter redeemed with a mint pass).
If she wins, she could call MergingPool.claimRewards() just after someone else has obtained the fighter number 3 (in other words, when fighters.length=3).
We know this attack vector could be hard to perform, but we have to report the consequences of mitigation. To solve the bad randomness introduced by this mitigation, we propose to implement something like FighterFarm.redeemMintPass() where the dna is obtained from an external source (for example, from a backend server) and cannot be manipulated by the caller.
Conclusions
In conclusion, the proposed mitigation solves the initial bad randomness due to too little dna combinations space. However, it doesnt solve the issue reported by #1017:
The malicious user can still forecast the outcome fighter attributes and claim the MergingPool reward when it is more convenient for him/her. Furthermore, it introduces the possibility to manipulate the msg.sender value to obtain a wanted dna and, so, a fighter with wanted valuable and rare attributes. We are going to report this comment as unmitigated and the attack vector above as a new finding.
