Nested Finance contest - Omik's results

The one-stop Defi app to build, manage and monetize your portfolio.

General Information

Platform: Code4rena

Start Date: 10/02/2022

Pot Size: $30,000 USDC

Total HM: 5

Participants: 24

Period: 3 days

Judge: harleythedog

Total Solo HM: 3

Id: 86

League: ETH

Nested Finance

Findings Distribution

Researcher Performance

Rank: 11/24

Findings: 2

Award: $431.11

🌟 Selected for report: 0

🚀 Solo Findings: 0

Findings Information

🌟 Selected for report: pauliax

Also found by: 0xliumin, Dravee, GreyArt, IllIllI, Omik, ShippooorDAO, WatchPug, bobi, csanuragjain, gzeon, kenzo, rfa, robee, samruna

Labels

bug
QA (Quality Assurance)
sponsor acknowledged

Awards

309.3509 USDC - $309.35

External Links

LOW: 1. Title : ETH may be stuck forever

Impact : In the https://code4rena.com/reports/2021-11-nested [M-08] the sponsored stated that this contract should not held any funds, and if there is any erc20 token accidentally send to this contract it is claimable by the owner through https://github.com/code-423n4/2022-02-nested/blob/main/contracts/NestedFactory.sol#L132 unlockTokens function, since this contract has a receive https://github.com/code-423n4/2022-02-nested/blob/main/contracts/NestedFactory.sol#L71 this contract can receive ETH, but there is no function to retrieve the ETH, therefore any ETH that was sent to this contract will be locked forever since the owner can't claim it also.

POC : https://github.com/code-423n4/2022-02-nested/blob/main/contracts/NestedFactory.sol#L71

Mitigation : Add require to make this contract only receive etc from WETH address.

Title : missing validation between _inputTokenAmount and actual token that was inputed

Impact : The _transferInputTokens function is handling the token transfer from the user to this contract, however there is missing check whether the _inputTokenAmount is equal to the actual token that was transfer to this address, In the case AMP token, there is an external call when doing a transfer, an attacker can cause a mismatch when the token was transfer to this address, the attacker transfer the AMP token directly to this contract which inflating the balance of this address, therefore the difference between the _inputTokenAmount and the actual balance that this contract has, would be massive.

POC :

https://github.com/code-423n4/2022-02-nested/blob/main/contracts/NestedFactory.sol#L505

Title : There is no limit on how many operator that can be added

Impact : In the https://github.com/code-423n4/2022-02-nested/blob/main/contracts/NestedFactory.sol#L100 the owner can add an operator, however there is no limit on how many operator can be added by the owner, if the operator inflated to a big value, the removeOperator would be failing on run out of gas, therefore the operator would be inflated and can't be removed.

POC : https://github.com/code-423n4/2022-02-nested/blob/main/contracts/NestedFactory.sol#L100

#0 - maximebrugel

2022-02-15T14:59:59Z

« ETH may be stuck forever » (Duplicated)

https://github.com/code-423n4/2022-02-nested-findings/issues/44

« Missing validation between _inputTokenAmount and actual token that was inputed » (Disputed)

We don’t want to revert if the token has fees on transfers.

« There is no limit on how many operator that can be added » (Acknowledged)

#1 - harleythedogC4

2022-02-27T18:44:17Z

The first point is better suited as a duplicate of #37 (low severity), since both do not mention that anyone can actually use the stuck eth to their advantage (which #44 describes). The third point is a valid observation but unlikely to cause any issues since the owner is a multisig behind a timelock.

#2 - harleythedogC4

2022-03-01T02:37:16Z

My personal judgements:

  1. "Title : ETH may be stuck forever". Valid and low-critical.
  2. "Title : missing validation between _inputTokenAmount and actual token that was inputed". The whole point of using the delta of the balance is to get the exact amount of tokens transferred in and not trust that it is equal to _inputTokenAmount. Invalid.
  3. "Title : There is no limit on how many operator that can be added". Valid and low-critical.

#3 - harleythedogC4

2022-03-03T02:30:25Z

Now, here is the methodology I used for calculating a score for each QA report. I first assigned each submission to be either non-critical (1 point), very-low-critical (5 points) or low-critical (10 points), depending on how severe/useful the issue is. The score of a QA report is the sum of these points, divided by the maximum number of points achieved by a QA report. This maximum number was 26 points, achieved by https://github.com/code-423n4/2022-02-nested-findings/issues/66.

The number of points achieved by this report is 20 points. Thus the final score of this QA report is (20/26)*100 = 77.

Findings Information

Awards

121.765 USDC - $121.76

Labels

bug
G (Gas Optimization)
sponsor confirmed

External Links

GAS : 1. Title: Unnecessary owner function call

Impact: In the https://github.com/code-423n4/2022-02-nested/blob/main/contracts/NestedFactory.sol#L134 it uses owner function call, instead of _owner, using _owner directly can save some gas

POC : https://github.com/code-423n4/2022-02-nested/blob/main/contracts/NestedFactory.sol#L134

Title: It cheaper to remove the && operator and make the 2 different require

POC : https://github.com/code-423n4/2022-02-nested/blob/main/contracts/NestedAsset.sol#L78

Mitigation :

require(_exists(_replicatedTokenId), "NA: INVALID_REPLICATED_TOKEN_ID"); require(tokenId != _replicatedTokenId, "NA: INVALID_REPLICATED_TOKEN_ID");

Title : It Cheaper to use 0 instead of empty string

Impact : change bytes32("") to bytes32(0) can save +- 3 gas, both check for zero bytes32

POC : https://github.com/code-423n4/2022-02-nested/blob/main/contracts/NestedFactory.sol#L101

Mitigation :

require(operator != bytes32(0), "NF: INVALID_OPERATOR_NAME");

Title : It cheaper to cached the operators to a memory instead use storage multiple times

Impact : In the removeOperator function it do the check in the loop by calling the operators storage, instead checking it with memory, multiple storage read is more expansive than doing multiple read from memory therefore saving the operator value to a memory first before checking inside a loop can make this call cheaper, just like addOperator function do.

POC : https://github.com/code-423n4/2022-02-nested/blob/main/contracts/NestedFactory.sol#L111

Mitigation :

function removeOperator(bytes32 operator) external override onlyOwner { bytes32[] memory operatorsCache = operators; uint256 operatorsLength = operatorsCache.length; for (uint256 i = 0; i < operatorsLength; i++) { if (operatorsCache[i] == operator) { operators[i] = operatorsCache[operatorsLength - 1]; operators.pop(); emit OperatorRemoved(operator); return; } } revert("NF: NON_EXISTENT_OPERATOR"); }

#0 - maximebrugel

2022-02-17T16:52:23Z

"Unnecessary owner function call" (Duplicated)

https://github.com/code-423n4/2022-02-nested-findings/issues/67

"It cheaper to remove the && operator and make the 2 different require" (Confirmed)

20 unit saved

"It Cheaper to use 0 instead of empty string" (Disputed)

No impact.

"It cheaper to cached the operators to a memory instead use storage multiple times" (Confirmed)

#1 - harleythedogC4

2022-03-13T03:35:28Z

My personal judgments:

  1. "Unnecessary owner function call". Valid and small-optimization.
  2. "remove the && operator". Valid and small-optimization.
  3. "It Cheaper to use 0 instead of empty string". Report claims it can save +-3 gas, which is confusing and implies it might spend more gas? Sponsor notes no difference so I will agree with sponsor. Invalid.
  4. "cached the operators to a memory". Valid and small-optimization.

#2 - harleythedogC4

2022-03-13T06:21:37Z

Now, here is the methodology I used for calculating a score for each gas report. I first assigned each submission to be either small-optimization (1 point), medium-optimization (5 points) or large-optimization (10 points), depending on how useful the optimization is. The score of a gas report is the sum of these points, divided by the maximum number of points achieved by a gas report. This maximum number was 10 points, achieved by #67.

The number of points achieved by this report is 3 points. Thus the final score of this gas report is (3/10)*100 = 30.

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