Neo Tokyo contest - 0xhacksmithh'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: 17/123

Findings: 2

Award: $385.13

QA:
grade-a
Gas:
grade-a

🌟 Selected for report: 0

šŸš€ Solo Findings: 0

[Low-01] When There are more than 2 Input arrays as function parameter, There should be a check whether these are of same length or not.

	function configureTimelockOptions (
		AssetType _assetType,
		uint256[] memory _timelockIds,
		uint256[] memory _encodedSettings 
	) external hasValidPermit(bytes32(uint256(_assetType)), CONFIGURE_TIMELOCKS) {
		for (uint256 i; i < _timelockIds.length; ) {
			timelockOptions[_assetType][_timelockIds[i]] = _encodedSettings[i];
			unchecked { ++i; }
		}
	}

There should be a check which ensure _timelockIds and _encodedSettings are of same length Instances(4)

File: https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L1737-L1746 https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L1760-L1773 https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L1783-L1791 https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L1802-L1808

[Low-02] Before making low level call, ensure target contract exist or not.

Instances(2)

File: contracts/staking/NeoTokyoStaker.sol https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L773 https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L802

[Low-03] Functions that may lead to DOS(Denial of Service)

Instances(2)

File: contracts/staking/NeoTokyoStaker.sol https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L710-L752 https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L1264-L1396

[Low-04] Precision loss

Due to rounding and multiplication before division, Code base suffer precision loss in multiple cases Instances(10)

File: contracts/staking/NeoTokyoStaker.sol https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L968-L970 https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L1098 https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L1155 https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L1388 https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L1389 https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L1390 https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L1391 https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L1623

[Low-05] Anyone can call claimReward() for others. Basically there is no access control present here

Instances(1)

File: contracts/staking/NeoTokyoStaker.sol https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L1409-L1411

[Low-06] getStakerPosition() may get confused with getStakerPositions()

When getStakerPositions() gives The position of the _stakeracross all asset types.``` where, ```getStakerPosition()``` givesThe list of token IDs of a particular Citizen type that have been staked by _staker.`

So during frontend integretion these two function may used by mistakely.

Recommended to make some name change. Instances(2)

File: contracts/staking/NeoTokyoStaker.sol https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L689 https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L710

[Low-07] default from Switch case should revert Otherwise withdraw() will get successful with invalid _assetType parameter.

Instances(1)

File: contracts/staking/NeoTokyoStaker.sol https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L1682-L1694

[NC-01] Lack of event emission for critical parameter change

Instances(10)

File: contracts/staking/NeoTokyoStaker.sol https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L1714 https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L1722 https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L1743 https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L1760-L1773 https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L1783-L1791 https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L1802-L1808 https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L1819 https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L1851
File: contracts/staking/BYTES2.sol https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/BYTES2.sol#L162-L166 https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/BYTES2.sol#L173-L177

[NC-02] Floating Pragma

Instances(2)

File: contracts/staking/NeoTokyoStaker.sol https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L2
File: contracts/staking/BYTES2.sol https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/BYTES2.sol#L2

[NC-03] For Modern and more readable code, update import usages

Instances(5)

File: contracts/staking/NeoTokyoStaker.sol https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L6-L8
File: contracts/staking/BYTES2.sol https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/BYTES2.sol#L7-L9

[NC-04] constructor lack zero address checks

Instances(2)

File: contracts/staking/NeoTokyoStaker.sol https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L588-L606
File: contracts/staking/BYTES2.sol https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/BYTES2.sol#L75-L85

[NC-05] Mandatory checks for safety

string memory vaultMultiplier = (_vaultId != 0)

No checks present whether vaultId is valid or not

_pools[_inputs[i].assetType].daoTax = _inputs[i].daoTax;

No upperbound check for daoTax, while setting it

vaultCreditMultiplier[_vaultCreditMultipliers[i]] = _multipliers[i];

same no upperbound check here as well

Instances(7)

File: contracts/staking/NeoTokyoStaker.sol https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L639 https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L665 https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L290-L292 https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L1825 https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L1807
File: contracts/staking/BYTES2.sol https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/BYTES2.sol#L75-85

[NC-06] CONSTANT redefine elsewhere

Use a single file for all system-wide CONSTANTS Instances(Multiple instances)

File: contracts/staking/NeoTokyoStaker.sol https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L191-L220
File: contracts/staking/BYTES2.sol https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/BYTES2.sol#L37-L40

[NC-07] Use private constant consistently

Instances(5)

File: contracts/staking/NeoTokyoStaker.sol https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L206-L220

[NC-08] constant should be value rather than a expression

Instances(1)

File: contracts/staking/NeoTokyoStaker.sol https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L203

[NC-09] CONSTANT values such as a call to keccake() should use immutable rather than constant

Instances(9)

File: contracts/staking/NeoTokyoStaker.sol https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L191 https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L194 https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L206 https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L209 https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L214 https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L217 https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L220
File: contracts/staking/BYTES2.sol https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/BYTES2.sol#L37-L40

[NC-10] Lock Pragma to specific version

Instances(2)

File: contracts/staking/NeoTokyoStaker.sol https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L2
File: contracts/staking/BYTES2.sol https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/BYTES2.sol#L2

[NC-11] Showing actual values (how result comes) in NATSPEC comments makes checking and reading code easier

Instances(2)

File: contracts/staking/NeoTokyoStaker.sol https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L191 https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L194

[NC-12] No need for duplicate imports

IERC20 comes automatically with ERC20. So need to import it separately.

Instances(1)

File: contracts/staking/BYTES2.sol https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/BYTES2.sol#L4-L5

[NC-13] Conflicting comment

Function NatSpec says @param _bytes The address of the BYTES 2.0 ERC-20 token contract. but its actually BYTES 1.0 Instances(1)

File: contracts/staking/BYTES2.sol https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/BYTES2.sol#L70

[NC-14] Presence of Unnamed parameter in Function

Instances(4)

File: contracts/staking/NeoTokyoStaker.sol https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L1045 https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L1661

[NC-15] Use of magic numbers

Instances(1)

File: contracts/staking/NeoTokyoStaker.sol https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L1098

[NC-16] There should be a check which ensure updated value should not equal to old one.

Instances(2)

File: contracts/staking/NeoTokyoStaker.sol https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L1855 https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L1856

#0 - c4-judge

2023-03-17T03:21:25Z

hansfriese marked the issue as grade-a

#1 - hansfriese

2023-04-04T08:58:20Z

L-01 and L-02 are out of scope.

[Gas-01] State Variables should be cached in stack variable rather than re-reading them from storage

Instances(8)

File: contracts/staking/NeoTokyoStaker.sol https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L716 https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L718 https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L733-L734 https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L1279 https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L1280 https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L1288 https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L1289

[Gas-02] Function that guaranteed to revert when called by normal users can be marked as payable

Instances(11)

File: contracts/staking/NeoTokyoStaker.sol https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L1851 https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L1819 https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L1802 https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L1783 https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L1760 https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L1737 https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L1721 https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L1708
File: File: contracts/staking/BYTES2.sol https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/BYTES2.sol#L140 https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/BYTES2.sol#L162 https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/BYTES2.sol#L173

[Gas-03] Multiple addresses mapping can be combined into a single mapping of an addresses to a struct where appropriate.

Saves a storage slot for the mapping. Depending on the circumstances and sizes of types, can avoid a Gsset (20000 gas) per mapping combined. Reads and subsequent writes can also be cheaper when a function requires both values and they both fit in the same storage slot. Finally, if both fields are accessed in the same function, can save ~42 gas per access due to not having to recalculate the key’s keccak256 hash (Gkeccak256 - 30 gas) and that calculation’s associated stack operations. Instances(5)

File: contracts/staking/NeoTokyoStaker.sol https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L280 https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L319 https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L326 https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L372 https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L405

[Gas-04] Code base making 2 times contract interaction

In contract NeoTokyoStaker.sol Function withdraw() calls IByteContract(BYTES).getReward(msg.sender); during withdrawing.

Then after contract BYTES2.sol call NeoTokyoStaker.sol via

               (
			uint256 reward,
			uint256 daoCommision
		) = IStaker(STAKER).claimReward(_to); 

Instead if we make some logic change we call directly claimReward() inside withdraw() and then pass corresponding parameter to BYTES.sol contract respectively. Instances(1)

File: contracts/staking/NeoTokyoStaker.sol https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L1673
File: contracts/staking/BYTES2.sol https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/BYTES2.sol#L120

[Gas-05] Avoid compound assignment operator in state variables

<x> += <y> costs more than <x> = <x> + <y> for state variables Instances(15)

File: contracts/staking/NeoTokyoStaker.sol https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L977 https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L1029 https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L1078 https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L1079 https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L1080 https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L1099 https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L1100 https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L1101 https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L1160 https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L1161 https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L1164 https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L1515 https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L1626 https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L1627 https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L1630

[Gas-06] Empty block should be removed or emit something

Instances(2)

File: contracts/staking/BYTES2.sol https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/BYTES2.sol#L189-L194 https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/BYTES2.sol#L204-L208

[Gas-07] Making constant variable private will save gas during deployment.

Instances(5)

File: contracts/staking/NeoTokyoStaker.sol https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L206-L220

[Gas-08] Use assembly to check for address(0x0)

Saves 6 gas per instance if using assembly to check for address(0)

File: contracts/staking/NeoTokyoStaker.sol File: contracts/staking/BYTES2.sol

[Gas-09] Struct can be packed into fewer storage slots

Instances(7)

File: contracts/staking/NeoTokyoStaker.sol https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L290-L292 https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L308-L311 https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L360-L363 https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L394-L398 https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L423-L428 https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L462-L468 https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L486-L490

[Gas-10] Optimize names to save gas

public/externalĀ function names andĀ publicĀ member variable names can be optimized to save gas. SeeĀ thisĀ link for an example of how it works. Below are the interfaces/abstract contracts that can be optimized so that the most frequently-called functions use the least amount of gas possible during method lookup. Method IDs that have two leading zero bytes can saveĀ 128 gasĀ each during deployment, and renaming functions to have lower method IDs will saveĀ 22 gasĀ per call,Ā per sorted position shifted. Instances(Multiple Instances)

File: contracts/staking/NeoTokyoStaker.sol File: contracts/staking/BYTES2.sol

[Gas-11] May use of Switch case increase code readability and save gas

Instances(1)

File: contracts/staking/NeoTokyoStaker.sol https://github.com/code-423n4/2023-03-neotokyo/blob/main/contracts/staking/NeoTokyoStaker.sol#L693-L699

[Gas-12] Use functions instead of modifier

File: contracts/staking/NeoTokyoStaker.sol File: contracts/staking/BYTES2.sol

[Gas-13] Setting constructor to payable can save gas

Saves ~13 gas per instances. Instances(2)

File: contracts/staking/NeoTokyoStaker.sol File: contracts/staking/BYTES2.sol

#0 - c4-judge

2023-03-17T04:35:52Z

hansfriese marked the issue as grade-a

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