AI Arena - 0xAadi'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: 209/283

Findings: 1

Award: $2.06

🌟 Selected for report: 0

🚀 Solo Findings: 0

Lines of code

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

Vulnerability details

The RankedBattle contract contains a staking factor calculation that may lead to imprecise and unfair point allocations during wins and losses in battles. This is due to the truncation of the square root calculation for staked amounts, which is particularly problematic for small stakes.

Impact

The imprecision in the staking factor calculation can result in disproportionate influence and reward points for users staking very small amounts, while potentially diluting the reward points for users with larger stakes. This undermines the fairness and integrity of the game and can distort the incentive structure for participation.

Proof of Concept

The staking factor is calculated using the _getStakingFactor() function, which takes the square root of the staked amount divided by 10**18. So the result is truncated to the nearest whole number, leading to a loss of precision. This is particularly severe for small stakes, where the result can be rounded up to 1, giving minimal stakes a disproportionate staking factor.

The relevant code from the RankedBattle contract is as follows:

        function _getStakingFactor(
            uint256 tokenId, 
            uint256 stakeAtRisk
        ) 
            private 
            view 
            returns (uint256) 
        {
@-->    uint256 stakingFactor_ = FixedPointMathLib.sqrt(
            (amountStaked[tokenId] + stakeAtRisk) / 10**18
        );
        if (stakingFactor_ == 0) {
@-->        stakingFactor_ = 1;
        }
        return stakingFactor_;
        }

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

The code which calculate points using stakingFactor is:

445:    points = stakingFactor[tokenId] * eloFactor;
.
481:    points = stakingFactor[tokenId] * eloFactor;

https://github.com/code-423n4/2024-02-ai-arena/blob/cd1a0e6d1b40168657d1aaee8223dc050e15f8cc/src/RankedBattle.sol#L445 https://github.com/code-423n4/2024-02-ai-arena/blob/cd1a0e6d1b40168657d1aaee8223dc050e15f8cc/src/RankedBattle.sol#L481

The issue can be illustrated with two users, Alice and Bob:

  • Alice stakes 1 wei-equivalent of NRN (0.000000000000000001 NRN).
  • Bob stakes 3.99 NRN.

The staking factor for Alice, based on the calculation, initially yields 0 due to the division and square root of a very small number. However, the contract's code enforces a minimum staking factor of 1, so Alice's staking factor is artificially set to 1.

For Bob, the staking factor calculation results in a value that is approximately 1 due to the round down in the calculation. Therefore, Bob's staking factor is also 1, the same as Alice's, despite his substantially larger stake.

The issue is that the staking factor for both Alice and Bob is calculated as 1, which does not accurately reflect the disparity in their staked amounts. This results in an unfair distribution of reward points, where Alice's negligible stake has the same weight as Bob's significant stake.

Tools Used

Manual review

To address the issue, the following steps are recommended:

  1. Scale Before Square Root: Multiply the staked amount by a significant scaling factor before performing the square root operation. This can help preserve precision when the square root of a small number is taken, as the result will be a larger number that, when truncated, will still reflect the relative size of the original stake.

  2. Minimum Staking Threshold: Introduce a minimum staking threshold to ensure that the staking factor is meaningful. This would prevent users from receiving a staking factor for negligible stakes and ensure that the staking factor accurately reflects the risk and investment of participants.

Assessed type

Math

#0 - c4-pre-sort

2024-02-24T08:15:39Z

raymondfam marked the issue as insufficient quality report

#1 - c4-pre-sort

2024-02-24T08:15:48Z

raymondfam marked the issue as duplicate of #38

#2 - c4-judge

2024-03-07T02:58:22Z

HickupHH3 changed the severity to 3 (High Risk)

#3 - c4-judge

2024-03-07T03:49:39Z

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