AI Arena - 0xPluto'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: 249/283

Findings: 1

Award: $0.23

🌟 Selected for report: 0

🚀 Solo Findings: 0

Lines of code

https://github.com/code-423n4/2024-02-ai-arena/blob/cd1a0e6d1b40168657d1aaee8223dc050e15f8cc/src/MergingPool.sol#L139

Vulnerability details

Impact

The claimRewards function in the MergingPool contract is vulnerable to a Denial of Service (DoS) attack due to unbounded loops. This can lead to a situation where users are unable to claim their rewards, effectively blocking access to the function.

Proof of Concept

Consider a scenario where a user manages to become a winner in a large number of rounds. When the claimRewards function is called, it iterates through all unclaimed rounds for the sender (from 0 to currentRountID). If the number of iterations is large enough, the transaction may exceed the block gas limit, resulting in a failure to claim rewards.

 function claimRewards( //@audit DoS attack
        string[] calldata modelURIs, 
        string[] calldata modelTypes,
        uint256[2][] calldata customAttributes
    ) 
        external 
    {
        uint256 winnersLength;
        uint32 claimIndex = 0;
        uint32 lowerBound = numRoundsClaimed[msg.sender];
        for (uint32 currentRound = lowerBound; currentRound < roundId; currentRound++) {
            numRoundsClaimed[msg.sender] += 1;
            winnersLength = winnerAddresses[currentRound].length;
            for (uint32 j = 0; j < winnersLength; j++) {
                if (msg.sender == winnerAddresses[currentRound][j]) {
                    _fighterFarmInstance.mintFromMergingPool(
                        msg.sender,
                        modelURIs[claimIndex],
                        modelTypes[claimIndex],
                        customAttributes[claimIndex]
                    );
                    claimIndex += 1;
                }
            }
        }
        if (claimIndex > 0) {
            emit Claimed(msg.sender, claimIndex);
        }
    }

Tools Used

Manual Analysis

Limit the Number of Rounds Processed: Introduce a parameter that limits the number of rounds that can be processed in a single transaction. This will prevent the function from exceeding the gas limit due to too many iterations.

function claimRewards(
    string[] calldata modelURIs, 
    string[] calldata modelTypes,
    uint256[2][] calldata customAttributes,
    uint32 maxRoundsToProcess // New parameter
) external {
    uint256 winnersLength;
    uint32 claimIndex = 0;
    uint32 lowerBound = numRoundsClaimed[msg.sender];
    uint32 upperBound = min(roundId, lowerBound + maxRoundsToProcess);
    
    for (uint32 currentRound = lowerBound; currentRound < upperBound; currentRound++) {
        numRoundsClaimed[msg.sender] += 1;
        winnersLength = winnerAddresses[currentRound].length;
        for (uint32 j = 0; j < winnersLength; j++) {
            if (msg.sender == winnerAddresses[currentRound][j]) {
                _fighterFarmInstance.mintFromMergingPool(
                    msg.sender,
                    modelURIs[claimIndex],
                    modelTypes[claimIndex],
                    customAttributes[claimIndex]
                );
                claimIndex += 1;
            }
        }
    }
    if (claimIndex > 0) {
        emit Claimed(msg.sender, claimIndex);
    }
}

Assessed type

DoS

#0 - c4-pre-sort

2024-02-24T00:04:00Z

raymondfam marked the issue as sufficient quality report

#1 - c4-pre-sort

2024-02-24T00:04:43Z

raymondfam marked the issue as duplicate of #1541

#2 - c4-judge

2024-03-11T13:01:31Z

HickupHH3 marked the issue as duplicate of #216

#3 - c4-judge

2024-03-11T13:08:05Z

HickupHH3 changed the severity to 2 (Med Risk)

#4 - c4-judge

2024-03-12T02:36:26Z

HickupHH3 marked the issue as partial-50

#5 - c4-judge

2024-03-21T02:58:14Z

HickupHH3 marked the issue as satisfactory

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