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
Rank: 145/283
Findings: 2
Award: $13.86
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: ahmedaghadi
Also found by: 0x13, 0xAleko, 0xDetermination, 0xKowalski, 0xPluto, 0xRiO, 0xvj, AlexCzm, Avci, BARW, BigVeezus, Cryptor, DeFiHackLabs, Draiakoo, Fitro, Giorgio, GoSlang, Greed, Honour, Kalogerone, KmanOfficial, Krace, McToady, MidgarAudits, MrPotatoMagic, Nyxaris, ReadyPlayer2, Ryonen, SovaSlava, SpicyMeatball, VAD37, _eperezok, alexzoid, almurhasan, btk, cu5t0mpeo, deadrxsezzz, djxploit, dvrkzy, emrekocak, erosjohn, evmboi32, fnanni, grearlake, inzinko, jesjupyter, jesusrod15, josephdara, ke1caM, klau5, ktg, ladboy233, merlinboii, nuthan2x, peanuts, pipidu83, pontifex, radev_sw, sl1, sobieski, soliditywala, t0x1c, taner2344, vnavascues, y4y, yovchev_yoan, zaevlad
0.2347 USDC - $0.23
https://github.com/code-423n4/2024-02-ai-arena/blob/main/src/RankedBattle.sol#L299-L305 https://github.com/code-423n4/2024-02-ai-arena/blob/main/src/MergingPool.sol#L149-L163
After a certain point, newly registered players and players who have stopped playing for a long time cannot claim the rewards.
After a few years roundId
will reach very high numbers. Since newly registered player's numRoundsClaimed[player]
starts with 0, all newly registered players cannot execute RankedBattle::claimNRN
and MergingPool::claimRewards
functions because of high gas consumption. It'll be higher than block gas limit.
https://github.com/code-423n4/2024-02-ai-arena/blob/main/src/RankedBattle.sol#L299-L305
https://github.com/code-423n4/2024-02-ai-arena/blob/main/src/MergingPool.sol#L149-L163
Manual Review
Newly registered player's numRoundsClaimed
value should start current roundId
.
If numRoundsClaimed[msg.sender] == 0
, it's unnecessary to make remaining calculations inside the loop like below. This change will reduce spent gas.
diff --git a/src/RankedBattle.sol#L299-L305 uint32 lowerBound = numRoundsClaimed[msg.sender]; + uint256 accumulatedPoints; for (uint32 currentRound = lowerBound; currentRound < roundId; currentRound++) { + accumulatedPoints = accumulatedPointsPerAddress[msg.sender][currentRound]; if (accumulatedPoints == 0){ lowerBound += 1; } + else{ nrnDistribution = getNrnDistribution(currentRound); claimableNRN += ( - accumulatedPointsPerAddress[msg.sender][currentRound] * nrnDistribution + accumulatedPoints * nrnDistribution ) / totalAccumulatedPoints[currentRound]; - numRoundsClaimed[msg.sender] += 1; + lowerBound += 1; + } } + numRoundsClaimed[msg.sender] = lowerBound;
DoS
#0 - c4-pre-sort
2024-02-25T02:22:58Z
raymondfam marked the issue as sufficient quality report
#1 - c4-pre-sort
2024-02-25T02:23:10Z
raymondfam marked the issue as duplicate of #1541
#2 - c4-judge
2024-03-11T13:00:36Z
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:43:52Z
HickupHH3 marked the issue as partial-50
#5 - c4-judge
2024-03-21T02:10:29Z
HickupHH3 marked the issue as satisfactory
🌟 Selected for report: 0xDetermination
Also found by: 0x11singh99, 0xAnah, 0xRiO, JcFichtner, K42, MatricksDeCoder, McToady, PetarTolev, Raihan, SAQ, SM3_SS, SY_S, Timenov, ahmedaghadi, al88nsk, dharma09, donkicha, emrekocak, favelanky, hunter_w3b, judeabara, kiqo, lrivo, lsaudit, merlinboii, mikesans, offside0011, oualidpro, peter, rekxor, shamsulhaq123, unique, yashgoel72, yovchev_yoan, ziyou-
13.6293 USDC - $13.63
numRoundsClaimed[msg.sender] == 0
it's unnecessary to calculate claimableNRN
If a player is newly registered or has stopped playing for a long time, there will be lots of 0 value in numRoundsClaimed
. For each 0 value there is unnecessary claimableNRN
calculation. Similar issue also can be found here
Also numRoundsClaimed[msg.sender]
should be cached. (This is mentioned in bot races but I wrote it in recommendation to make it clear)
diff --git a/src/RankedBattle.sol#L299-L305 uint32 lowerBound = numRoundsClaimed[msg.sender]; + uint256 accumulatedPoints; for (uint32 currentRound = lowerBound; currentRound < roundId; currentRound++) { + accumulatedPoints = accumulatedPointsPerAddress[msg.sender][currentRound]; if (accumulatedPoints == 0){ lowerBound += 1; } + else{ nrnDistribution = getNrnDistribution(currentRound); claimableNRN += ( - accumulatedPointsPerAddress[msg.sender][currentRound] * nrnDistribution + accumulatedPoints * nrnDistribution ) / totalAccumulatedPoints[currentRound]; - numRoundsClaimed[msg.sender] += 1; + lowerBound += 1; + } } + numRoundsClaimed[msg.sender] = lowerBound;
This line run already in addAttributeProbabilities
function.
diff --git a/src/AiArenaHelper.sol#L44-L51 // Initialize the probabilities for each attribute addAttributeProbabilities(0, probabilities); uint256 attributesLength = attributes.length; for (uint8 i = 0; i < attributesLength; i++) { - attributeProbabilities[0][attributes[i]] = probabilities[i]; attributeToDnaDivisor[attributes[i]] = defaultAttributeDivisor[i]; }
#0 - raymondfam
2024-02-25T22:18:44Z
G1 to #1541
#1 - c4-pre-sort
2024-02-25T22:18:51Z
raymondfam marked the issue as sufficient quality report
#2 - c4-judge
2024-03-12T02:47:44Z
HickupHH3 marked the issue as grade-b