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: 178/283
Findings: 2
Award: $7.33
π Selected for report: 0
π Solo Findings: 0
π Selected for report: nuthan2x
Also found by: 0xE1, 0xblackskull, 0xgrbr, 0xvj, Greed, McToady, MidgarAudits, PetarTolev, Sabit, SovaSlava, SpicyMeatball, Timenov, Tychai0s, _eperezok, alexxander, btk, c0pp3rscr3w3r, favelanky, jesjupyter, josephdara, juancito, klau5, kutugu, lil_eth, merlinboii, pynschon, sandy, shaflow2, zaevlad
7.2869 USDC - $7.29
https://github.com/code-423n4/2024-02-ai-arena/blob/main/src/Neuron.sol#L93 https://github.com/code-423n4/2024-02-ai-arena/blob/main/src/Neuron.sol#L101 https://github.com/code-423n4/2024-02-ai-arena/blob/main/src/Neuron.sol#L109
The contract Neuron.sol the functions to add addresses to specific roles minter, staker and spender, there is no corresponding functionality provided to revoke these roles once assigned.
In the Neuron.sol contract, while there are functions provided for assigning specific roles minters, stakers, and spenders addresses, the contract lacks the essential mechanisms for revoking these roles once they have been granted. This omission limits the contract's ability to adapt to changes or respond to security concerns by removing roles from addresses as necessary.
The inability to revoke roles from addresses can lead to several issues:
Operational Rigidity: Once an address is assigned a role, the contract lacks the flexibility to adapt to changes such as role reallocation, addressing compromised security, or merely updating the set of addresses holding a specific role.
Contract Management Limitations: Without the ability to revoke roles, the contract's management becomes cumbersome, particularly in dynamic environments where changes to roles are expected. This limitation may necessitate deploying a new contract or implementing additional layers of management logic outside the smart contract to handle role assignments dynamically.
It's recommended to implement corresponding functions to revoke each role (minter
, staker
, and spender
) that can be called by the contract owner or another designated authority within the contract. These functions should ensure that only authorized parties can remove roles, with adequate checks.
/// @notice Revokes a minter role from an address. /// @param minterAddress The address to be removed from the minter role. function revokeMinter(address minterAddress) external { require(msg.sender == _ownerAddress); revokeRole(MINTER_ROLE, minterAddress); emit RoleRevoked(MINTER_ROLE, minterAddress, msg.sender); } /// @notice Revokes a staker role from an address. /// @param stakerAddress The address to be removed from the staker role. function revokeStaker(address stakerAddress) external { require(msg.sender == _ownerAddress); revokeRole(STAKER_ROLE, stakerAddress); emit RoleRevoked(STAKER_ROLE, stakerAddress, msg.sender); } /// @notice Revokes a spender role from an address. /// @param spenderAddress The address to be removed from the spender role. function revokeSpender(address spenderAddress) external { require(msg.sender == _ownerAddress); revokeRole(SPENDER_ROLE, spenderAddress); emit RoleRevoked(SPENDER_ROLE, spenderAddress, msg.sender); }
Access Control
#0 - c4-pre-sort
2024-02-22T05:11:41Z
raymondfam marked the issue as insufficient quality report
#1 - c4-pre-sort
2024-02-22T05:11:49Z
raymondfam marked the issue as duplicate of #20
#2 - c4-judge
2024-03-05T07:39:43Z
HickupHH3 marked the issue as partial-25
#3 - HickupHH3
2024-03-05T07:40:02Z
fails to mention the underlying vuln of lacking admin role
π Selected for report: klau5
Also found by: 0rpse, 0xBinChook, 0xDetermination, 0xGreyWolf, 0xLogos, 0xWallSecurity, 0xaghas, 0xgrbr, 0xkaju, 0xlyov, AlexCzm, BARW, Blank_Space, BoRonGod, Daniel526, DanielArmstrong, Draiakoo, FloatingPragma, Giorgio, Greed, Jorgect, Matue, McToady, MidgarAudits, Nyxaris, PUSH0, PedroZurdo, Pelz, PoeAudits, Silvermist, SpicyMeatball, Tekken, Tricko, Tumelo_Crypto, VAD37, WoolCentaur, Zac, alexzoid, andywer, aslanbek, bgsmallerbear, cats, d3e4, desaperh, dimulski, dutra, erosjohn, evmboi32, favelanky, fnanni, forkforkdog, gesha17, givn, grearlake, haxatron, honey-k12, iamandreiski, immeas, juancito, kaveyjoe, ke1caM, kiqo, klau5, korok, lil_eth, lsaudit, n0kto, ni8mare, niser93, pa6kuda, peanuts, peter, shaka, sl1, soliditywala, solmaxis69, t0x1c, tallo, thank_you, tpiliposian, visualbits, vnavascues, web3pwn, yotov721
0.0352 USDC - $0.04
https://github.com/code-423n4/2024-02-ai-arena/blob/main/src/FighterFarm.sol#L212
The _createNewFighter function may be susceptible to forcible revert attacks due to the call to _safeMint
within its body. Since _safeMint
triggers the ERC721 Transfer
event, if the recipient address is a contract, it will invoke the onERC721Received
function on the recipient contract.
The design of this function introduces a potential exploit vector related to the reRoll
function, which allows users to spend $NRN tokens to reroll the attributes of their fighters. Malicious actors or contracts could exploit the ability to forcibly revert transactions to avoid the cost associated with rerolling attributes until they obtain a fighter with desired attributes.
Modify the onERC721Received function in the Foundry test file FighterFarm.t.sol as follows:
function onERC721Received(address, address, uint256, bytes memory) public returns (bytes4) { // Handle the token transfer here ( address owner, uint256[6] memory attr, uint256 weight, uint256 element, , , uint16 generation ) = _fighterFarmContract.getAllFighterInfo(0); // Revert the transaction forcibly if the attributes do not meet specific // criteria to prevent spending $NRN tokens on an unwanted random reroll outcome. if (attr[1] != 1) { return bytes4(0x0); } else { return this.onERC721Received.selector; } }
And now run forge tests:
forge test --mt testReroll -vv Failing tests: Encountered 2 failing tests in test/FighterFarm.t.sol:FighterFarmTest [FAIL. Reason: ERC721: transfer to non ERC721Receiver implementer] testReroll() (gas: 444802) [FAIL. Reason: ERC721: transfer to non ERC721Receiver implementer] testRerollRevertWhenLimitExceeded() (gas: 444822)
VSCode, foundry
Require users to commit to the attributes of the fighter or the outcome of the reRoll
before the minting transaction, reducing the incentive to revert the transaction after seeing the results.
Other
#0 - c4-pre-sort
2024-02-23T03:55:39Z
raymondfam marked the issue as sufficient quality report
#1 - c4-pre-sort
2024-02-23T03:55:56Z
raymondfam marked the issue as duplicate of #53
#2 - c4-judge
2024-03-06T03:46:08Z
HickupHH3 marked the issue as satisfactory
#3 - c4-judge
2024-03-15T02:10:54Z
HickupHH3 changed the severity to 2 (Med Risk)
#4 - c4-judge
2024-03-22T04:21:44Z
HickupHH3 marked the issue as duplicate of #376