Neo Tokyo contest - fatherOfBlocks's results

A staking contract for the crypto gaming illuminati.

General Information

Platform: Code4rena

Start Date: 08/03/2023

Pot Size: $60,500 USDC

Total HM: 2

Participants: 123

Period: 7 days

Judge: hansfriese

Id: 220

League: ETH

Neo Tokyo

Findings Distribution

Researcher Performance

Rank: 58/123

Findings: 2

Award: $48.97

QA:
grade-b
Gas:
grade-b

🌟 Selected for report: 0

🚀 Solo Findings: 0

NeoTokyoStaker.sol

  • L588 - In the constructor it is allowed to enter zero addresses, this is a problem, since if that happened most of the functionalities would be disabled.

  • L690/691 - The getStakerPosition() function has two inputs and inside they are used in the opposite order, this makes the order counterintuitive, the correct thing would be AssetType _assetType, address _staker.

  • L2 - Pragma float This contracts in scope are floating the pragma version.

  • L875/897/927/995/1010/1044/1057/1124/1137 - In the function _stakeS1Citizen()/_stakeS2Citizen()/_stakeBytes()/_stakeLP() two low level calls are made, this is done in the code without respecting the check effect interact pattern and it is also done at the beginning of the function without being necessary and can be done almost at the end of the function.

  • L1274 - The way in which this if is implemented: "if (pool.totalPoints != 0)" is quite uncomfortable to visualize, the correct thing to have less indentation is this: if (pool.totalPoints == 0) return (0, 0); and then continue with the code.

BYTES2.sol

  • L2 - Pragma float This contracts in scope are floating the pragma version.

  • L101/102 - In the upgradeBytes() function a IByteContract burn is made, but the check effect interact pattern is not respected. It would be advisable to follow this pattern.

  • L75 - In the constructor it is allowed to enter zero addresses, this is a problem, since if that happened most of the functionalities would be disabled.

  • L114 - The documentation says that only the S1 Citizen only calls it, but this function is external and it doesn't have any modifier, therefore anyone can call it, this is a contradiction between the function and its documentation.

#0 - c4-judge

2023-03-17T03:18:35Z

hansfriese marked the issue as grade-b

BYTES2.sol

  • L150/151/154 - It ends up being more comfortable to visualize and execute gas costs directly _mint(TREASURY, _amount * 2 / 3);

NeoTokyoStaker.sol

  • L631/632/638/640/664/666/903/904/939/943/969/948/949/950/962/963/966/969/971/977/1016/1017/1022/1023/1140/ 1159/1153/1164/1220/1221/1280/1281/1282/1289/1290/1292/1342/1343/1355/1357/1378/1379 - A variable is created in memory that will only be used once, therefore it could be avoided and used directly where the operation is necessary.

  • L1823/1824/1825/1830/1831/1834/1837 - Within the for loop, the _inputs[i] parameter is used multiple times, therefore, in order not to go through each line and search for i, it is less expensive to create a variable in memory. The same thing happens with _inputs[i].assetType and _inputs[i].rewardWindows[j], therefore other variables could be created in memories with these parameters.

#0 - c4-judge

2023-03-17T04:33:05Z

hansfriese marked the issue as grade-b

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