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: 168/283
Findings: 3
Award: $9.04
π Selected for report: 0
π Solo Findings: 0
π Selected for report: Aamir
Also found by: 0rpse, 0x11singh99, 0x13, 0xAlix2, 0xAsen, 0xBinChook, 0xCiphky, 0xE1, 0xKowalski, 0xLogos, 0xWallSecurity, 0xaghas, 0xbranded, 0xlemon, 0xlyov, 0xpoor4ever, 0xprinc, 0xvj, ADM, Aymen0909, BARW, Bauchibred, Breeje, CodeWasp, DMoore, DeFiHackLabs, Draiakoo, Fulum, GhK3Ndf, Greed, Jorgect, Josh4324, Kalogerone, KmanOfficial, Krace, Limbooo, McToady, MidgarAudits, MrPotatoMagic, PedroZurdo, Pelz, Ryonen, SovaSlava, SpicyMeatball, Tendency, Timenov, ZanyBonzy, _eperezok, al88nsk, alexxander, alexzoid, aslanbek, blutorque, btk, cartlex_, cats, csanuragjain, deadrxsezzz, denzi_, devblixt, dimulski, djxploit, erosjohn, evmboi32, fnanni, grearlake, haxatron, hulkvision, immeas, israeladelaja, jaydhales, jesjupyter, jnforja, josephdara, juancito, kiqo, klau5, korok, krikolkk, ktg, kutugu, ladboy233, lil_eth, m4ttm, matejdb, merlinboii, n0kto, ni8mare, novamanbg, nuthan2x, oualidpro, pa6kuda, peter, petro_1912, pkqs90, pynschon, sandy, sashik_eth, shaflow2, shaka, sobieski, soliditywala, solmaxis69, stackachu, tallo, thank_you, tpiliposian, ubl4nk, visualbits, vnavascues, web3pwn, xchen1130, zhaojohnson
0.0037 USDC - $0.00
https://github.com/code-423n4/2024-02-ai-arena/blob/main/src/GameItems.sol#L291
In GameItem.sol safeTransferFrom() use
require(allGameItemAttributes[tokenId].transferable)
make sure that non-transferable cannot be transfer. use safeBatchTransferFrom can bypass this check.
https://github.com/code-423n4/2024-02-ai-arena/blob/main/src/GameItems.sol#L291
Other
#0 - c4-pre-sort
2024-02-22T04:25:48Z
raymondfam marked the issue as sufficient quality report
#1 - c4-pre-sort
2024-02-22T04:26:12Z
raymondfam marked the issue as insufficient quality report
#2 - c4-pre-sort
2024-02-22T04:26:19Z
raymondfam marked the issue as duplicate of #18
#3 - c4-pre-sort
2024-02-26T00:29:25Z
raymondfam marked the issue as duplicate of #575
#4 - raymondfam
2024-02-26T00:34:47Z
Inadequate elaboration on the exploit.
#5 - c4-judge
2024-03-05T04:47:39Z
HickupHH3 changed the severity to 3 (High Risk)
#6 - c4-judge
2024-03-05T04:56:55Z
HickupHH3 marked the issue as satisfactory
π 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
There are two scenarios here that could lead to a permanent DoS.
Player win more than ten rounds.
Consider this scenario:
If a player has never claimed rewards and several rounds have passed, and the player has won more than ten rounds.
claimRewards -> mintFromMergingPool -> _createNewFighter
in _createNewFighter there is a check
require(balanceOf(to) < MAX_FIGHTERS_ALLOWED);
MAX_FIGHTERS_ALLOWED is 10, this will always revert and lead to a permanent DoS.
unbounded for-loop claimRewards() allows the user to batch claim rewards for multiple rounds. There is a similar issue in the bot race report, but miss this one. If a player has never claimed rewards and several rounds have passed, the roundID value become very large. When the player attempts to claim rewards and currentRound now is 0, and entering a for loop, it may result in a permanent DoS where the player is unable to claim rewards.
Player loses rewards.
Better approach is to allow players to choose a specifying range of roundIDs in the claimRewards() to batch claim rewards.
DoS
#0 - c4-pre-sort
2024-02-22T09:15:52Z
raymondfam marked the issue as sufficient quality report
#1 - c4-pre-sort
2024-02-22T09:16:05Z
raymondfam marked the issue as duplicate of #216
#2 - c4-judge
2024-03-11T12:52:21Z
HickupHH3 marked the issue as satisfactory
#3 - c4-judge
2024-03-21T02:58:22Z
HickupHH3 removed the grade
#4 - c4-judge
2024-03-21T02:58:26Z
HickupHH3 marked the issue as satisfactory
π Selected for report: givn
Also found by: 0x11singh99, 0xAkira, 0xBinChook, 0xDetermination, 0xMosh, 0xStriker, 0xmystery, 14si2o_Flint, 7ashraf, Aamir, AlexCzm, BARW, Bauchibred, BenasVol, BigVeezus, Blank_Space, Bube, DarkTower, DeFiHackLabs, EagleSecurity, KmanOfficial, Krace, McToady, MrPotatoMagic, PetarTolev, Rolezn, SHA_256, SpicyMeatball, Tekken, Timenov, ZanyBonzy, agadzhalov, alexzoid, boredpukar, btk, cartlex_, dimulski, forkforkdog, haxatron, immeas, jesjupyter, juancito, kartik_giri_47538, klau5, lsaudit, merlinboii, nuthan2x, offside0011, oualidpro, peter, radev_sw, rekxor, rspadi, shaflow2, shaka, swizz, vnavascues, yotov721, yovchev_yoan
8.8123 USDC - $8.81
fighterCreatedEmitter() is public, allowing anyone to arbitrarily modify the data storing the new Fighter NFT.
https://github.com/code-423n4/2024-02-ai-arena/blob/main/src/FighterOps.sol#L53
/// @notice Emits a FighterCreated event. function fighterCreatedEmitter( uint256 id, uint256 weight, uint256 element, uint8 generation ) public { emit FighterCreated(id, weight, element, generation); }
There are some senarios:
https://github.com/code-423n4/2024-02-ai-arena/blob/main/src/VoltageManager.sol#L110
ownerVoltage[spender] -= voltageSpent;
It is recommended to separate replenishVoltage into a standalone function.
https://github.com/code-423n4/2024-02-ai-arena/blob/main/src/VoltageManager.sol#L94
require(ownerVoltage[msg.sender] < 100);
The owner can add admin access for a user through adjustAdminAccess(). Multiple users may have admin access. setTokenURI() and createGameItem() are called by a user with admin access. After createGameItem(), other users with admin access can freely modify the tokenURI using setTokenURI.
https://github.com/code-423n4/2024-02-ai-arena/blob/main/src/GameItems.sol#L194
function setTokenURI(uint256 tokenId, string memory _tokenURI) public { require(isAdmin[msg.sender]); _tokenURIs[tokenId] = _tokenURI; }
The value of the NFTs depends on their metadata which includes critical information such as traits, rarity, images, etc.
Additionally, they can freely set non-existent tokenID and _tokenURI.
Bypass the check for uri()
if (bytes(customURI).length > 0)
.
Return non-existing tokenID along with its fake metadata.
This may mislead users.
When using the transferFrom function of an ERC721 contract to send an NFT, if the receiving address is a smart contract and does not support ERC721, the NFT can be permanently lost.
https://github.com/code-423n4/2024-02-ai-arena/blob/main/src/FighterFarm.sol#L338
function transferFrom( address from, address to, uint256 tokenId ) public override(ERC721, IERC721) { require(_ableToTransfer(tokenId, to)); _transfer(from, to, tokenId); }
Recommendation: Ensure receiving contract have onERC721Received method.
bpsLostPerLoss is adjusted by the msg.sender with isAdmin role, and there are no upper or lower limits. When calculating curStakeAtRisk, possible precision loss.
https://github.com/code-423n4/2024-02-ai-arena/blob/main/src/RankedBattle.sol#L439
curStakeAtRisk = (bpsLostPerLoss * (amountStaked[tokenId] + stakeAtRisk)) / 10**4;
Causing users unable to reclaim stake-at-risk puts the NRN back into their staking pool.
#0 - raymondfam
2024-02-26T04:39:44Z
Adequate amount of L and NC entailed.
#1 - c4-pre-sort
2024-02-26T04:39:48Z
raymondfam marked the issue as sufficient quality report
#2 - HickupHH3
2024-03-11T03:26:00Z
#1589: R #1534: L L1: R L2: R L3: R L4: R L5: R
#3 - c4-judge
2024-03-18T04:47:26Z
HickupHH3 marked the issue as grade-b