Closed c4-bot-6 closed 8 months ago
raymondfam marked the issue as insufficient quality report
raymondfam marked the issue as duplicate of #53
HickupHH3 marked the issue as satisfactory
HickupHH3 changed the severity to 3 (High Risk)
HickupHH3 changed the severity to 2 (Med Risk)
HickupHH3 marked the issue as duplicate of #376
Lines of code
https://github.com/code-423n4/2024-02-ai-arena/blob/main/src/FighterFarm.sol#L370-L391
Vulnerability details
Impact
Users can determine the stats of their fighters at will. Devalues "rare" fighters.
Proof of Concept
This exploit relies on the fighter being transferable.
The core issue is how the contract generates the fighter's dna. The dna generation on line https://github.com/code-423n4/2024-02-ai-arena/blob/main/src/FighterFarm.sol#L379
Including msg.sender with the hashing function makes the function non-deterministic. This allows the user to transfer their fighter to another address they control for a different result when calling the reRoll function. This can be further abused using tools like foundry to simulate the result of the reRoll function from different addresses.
The following code can be added to the test/FighterFarm.t.sol to demonstrate the vulnerability.
Note: The test should alter the following import before running the test:
This results in the following logs:
This particular example is only searching for attribute values >= 5. This can replicated to search for specific values of the fighter's element, weight and attributes. This gives players with the capability of exploiting the reRoll logic a significant and unfair advantage.
Once the system is deployed, it is even easier to write a script to abuse the reRoll function by forking the chain and calling the function directly.
Tools Used
Foundry, manual review
Recommended Mitigation Steps
There are two solutions to this problem.
The most robust solution is to receive random numbers using a service like Chainlink's VRF. This however, would require significant changes to the codebase and system design. The lesser solution in the same vein is for the project to compute random numbers off chain themselves and supply them to the contract, although implementing such a system is non-trivial.
The more reasonable solution would be to only use variables independent of user influence in the hash function. Removing msg.sender in line 379:
This leaves the hash function with variables outside the user's control, and the numRerolls variable acts like a nonce value, incrementing on each reroll ensuring the hash is different than before. This does, however, mean that the reRoll function is still deterministic such that users can pre-determine what the rerolls for each token will be. They will be able to pick from attribute profiles for as many rerolls they have remaining. This solution will no longer allow the user to select exactly the attributes they want.
Assessed type
Other