Closed c4-bot-6 closed 7 months ago
raymondfam marked the issue as sufficient quality report
raymondfam marked the issue as duplicate of #53
HickupHH3 marked the issue as satisfactory
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/cd1a0e6d1b40168657d1aaee8223dc050e15f8cc/src/FighterFarm.sol#L214 https://github.com/code-423n4/2024-02-ai-arena/blob/cd1a0e6d1b40168657d1aaee8223dc050e15f8cc/src/FighterFarm.sol#L254 https://github.com/code-423n4/2024-02-ai-arena/blob/cd1a0e6d1b40168657d1aaee8223dc050e15f8cc/src/FighterFarm.sol#L379 https://github.com/code-423n4/2024-02-ai-arena/blob/cd1a0e6d1b40168657d1aaee8223dc050e15f8cc/src/FighterFarm.sol#L324
Vulnerability details
The protocol's ERC721 fighters consist of a variety of attributes. This includes base attributes (element, weight, and dna), as well as physical attributes for each of the fighters 6 body parts (head, eyes, mouth, etc.)
Users should not be able to pre-compute inputs that allow them to claim fighters with the attributes they desire.
The current process of generating dna which directly impacts fighter attributes is based on a set formulas, which are easily viewable in
FighterFarm.sol
, the most common one for calculating dna is seen below.It should be noted the
FighterFarm::reRoll
uses a slight variation of the common dna formula but this doesn't increase the difficulty of manipulation.Since the common formula for dna has only 2 inputs, one of which (
msg.sender
) is under control of the user, it becomes trivially easy to solve this formula for the length of thefighters
at which the user should callclaimFighter
to mint a fighter with their desired attributes. A function doing such pre-computation for a specified address is included below.Logs result:
The reason a successful dna string is considered to be one in which
dna % 31 == 30
is because this is the way to ensure max weight whenclaimFighter
reaches the FighterFarm::_createFighterBase step. This example focused on achieving max weight but solving for various weights or any specific element is also possible.Impact
This vulnerability impacts all public / external functions which can result in the minting of a fighter these being:
FighterFarm::claimFighters - mint pass holder can calculate
fighters.length
value at which they should claim for desired attributesFighterFarm::redeemMintPass - mint pass holder can calculate values that results in their desired attributes without having to wait for a specified
fighters.length
to mint the fighter. Some examples that yield max weight when passed as dna argument are 23, 47, 60, 70, 83 ...etc.FighterFarm::reRoll - fighter owners can calculate what the result of calling
reRoll
for their fighter will be before spending the NRN to actually perform the action. Which leads to loss of protocol revenue as some users will notreRoll
if they know they will receive a fighter with undesirable attributes.FighterFarm::mintFromMergingPool - not directly impacted because it only allows the officially deployed MergingPool to call it
Proof of Concept
Test setup
forge test --mt testClaimMaxWeightFighter
Tools Used
Recommended Mitigation Steps
Due to the importance of randomness for the integrity of a fair game the current "randomness" should be replaced with a secure and verifiable source of randomness from Chainlink VRF which is currently available on Arbitrum.
Assessed type
Other