AI Arena - 7ashraf's results

In AI Arena you train an AI character to battle in a platform fighting game. Imagine a cross between Pokémon and Super Smash Bros, but the characters are AIs, and you can train them to learn almost any skill in preparation for battle.

General Information

Platform: Code4rena

Start Date: 09/02/2024

Pot Size: $60,500 USDC

Total HM: 17

Participants: 283

Period: 12 days

Judge:

Id: 328

League: ETH

AI Arena

Findings Distribution

Researcher Performance

Rank: 172/283

Findings: 1

Award: $8.81

🌟 Selected for report: 0

🚀 Solo Findings: 0

Quality Assurance Report

Summary

The QA report flags important issues and offers fixes for better project performance and security. It advises against accidentally adding new fighter types and stresses the importance of checking for existing stakeholders. It also notes potential security risks like unbounded loops and missing reentrancy locks. Recommendations include avoiding hardcoded values and simplifying complex functions for clearer code. Following these suggestions will enhance the project's overall quality and security.

Issue NumberIssue TitleNumber of Instances
L-01More Fighter types can be added by mistake1
L-02Check if staker already exists before adding1
L-03Possible dos for unbounded loop1
L-04Require amount to be greater than zero1
L-05Add re-entrance lock2
N-01Empty string is passed to the function, avoid hardcoded empty strings1
N-02Save String as a constant instead of hardcoding it in the function3
N-03Function should be allowed to be called only once1
N-04Avoid on-chain computation1
N-05Function is so clumped1

[L-01] More Fighter types can be added by mistake

The function can possibly add new fighter types if not handled correctly, adding un-wanted logic

Instances

    function incrementGeneration(uint8 fighterType) external returns (uint8) {
        require(msg.sender == _ownerAddress);
        generation[fighterType] += 1;
        maxRerollsAllowed[fighterType] += 1;
        return generation[fighterType];
    }

Mitigation

  • Check for fighter type either 0 or 1 before performing logic, revert if an invalid fighter type is called

[L-02] Check if a staker already exists before adding

Instances

    function addStaker(address newStaker) external {
        require(msg.sender == _ownerAddress);
        hasStakerRole[newStaker] = true;
    }

Function Should emit an event

Instances

    function addStaker(address newStaker) external {
        require(msg.sender == _ownerAddress);
        hasStakerRole[newStaker] = true;
    }

[L-03] Possible dos for unbounded loop

Instances

        for (uint16 i = 0; i < mintpassIdsToBurn.length; i++) {
            require(msg.sender == _mintpassInstance.ownerOf(mintpassIdsToBurn[i]));
            _mintpassInstance.burn(mintpassIdsToBurn[i]);
            _createNewFighter(
                msg.sender, 
                uint256(keccak256(abi.encode(mintPassDnas[i]))), 
                modelHashes[i], 
                modelTypes[i],
                fighterTypes[i],
                iconsTypes[i],
                [uint256(100), uint256(100)]
            );
        }

[L-04] Require amount to be greater than zero

Instances

            amount = amountStaked[tokenId];

[L-05] Add re-entrancy lock

Instances

function reRoll(uint8 tokenId, uint8 fighterType) public
function stakeNRN(uint256 amount, uint256 tokenId) external

[N-01] An Empty string is passed to the function, avoid hardcoded empty strings

Instances

        _safeTransfer(from, to, tokenId, "");

[N-02] Save String as a constant instead of hardcoding it in the function

Instances

    function contractURI() public pure returns (string memory) {
        return "ipfs://bafybeifztjs4yuwhqi7bvzhw2ufksynkoiwxss2gnti6j4v25l7iwz7y44";
    }
    constructor(address ownerAddress, address treasuryAddress_) ERC1155("https://ipfs.io/ipfs/") 
 function contractURI() public pure returns (string memory) {
        return "ipfs://bafybeih3witscmml3padf4qxbea5jh4rl2xp67aydqvqsxmyuzipwtpnii";
    }

[N-03] Function should be allowed to be called only once

Instances

    function instantiateNeuronContract(address nrnAddress) external {
        require(msg.sender == _ownerAddress);
        _neuronInstance = Neuron(nrnAddress);
    }

[N-04] Avoid on-chain computation

Instances

        rankedNrnDistribution[0] = 5000 * 10**18;

[N-05] Function is so clumped

The function mentioned below is very messy and needs some cleaning

Instance

    function _addResultPoints(
        uint8 battleResult, 
        uint256 tokenId, 
        uint256 eloFactor, 
        uint256 mergingPortion,
        address fighterOwner
    ) 

Mitigation

  • Consider splitting the logic of the function to make it clearer

#0 - raymondfam

2024-02-26T04:01:45Z

Adequate amount of L and NC albeit with inadequate elaboration.

#1 - c4-pre-sort

2024-02-26T04:02:15Z

raymondfam marked the issue as sufficient quality report

#2 - c4-judge

2024-03-19T04:17:46Z

HickupHH3 marked the issue as grade-c

#3 - c4-judge

2024-03-19T04:18:48Z

HickupHH3 marked the issue as grade-b

AuditHub

A portfolio for auditors, a security profile for protocols, a hub for web3 security.

Built bymalatrax © 2024

Auditors

Browse

Contests

Browse

Get in touch

ContactTwitter