Nibbl contest - hansfriese's results

NFT fractionalization protocol with guaranteed liquidity and price based buyout.

General Information

Platform: Code4rena

Start Date: 21/06/2022

Pot Size: $30,000 USDC

Total HM: 12

Participants: 96

Period: 3 days

Judge: HardlyDifficult

Total Solo HM: 5

Id: 140

League: ETH

Nibbl

Findings Distribution

Researcher Performance

Rank: 2/96

Findings: 4

Award: $3,019.73

🌟 Selected for report: 1

πŸš€ Solo Findings: 1

Findings Information

🌟 Selected for report: WatchPug

Also found by: hansfriese

Labels

bug
duplicate
2 (Med Risk)
sponsor acknowledged

Awards

631.623 USDC - $631.62

External Links

Lines of code

https://github.com/code-423n4/2022-06-nibbl/blob/main/contracts/Twav/Twav.sol#L40

Vulnerability details

Impact

Twav._getTwav() might revert when it should work properly. In this case, the main functions like NibblVault.buy() and NibblVault.sell() will revert also.

Proof of Concept

According to the logic, Twav.lastBlockTimeStamp saves a modularized timestamp so current timestamp might be smaller than the previous one. So (_twavObservationCurrent.timestamp - _twavObservationPrev.timestamp) might meet the underflow error.

Tools Used

Solidity Visual Developer of VSCode

We can use unchecked calculation for the above calculation. We can modify L40 like below.

uint32 _timeElapsed; unchecked { _timeElapsed = _twavObservationCurrent.timestamp - _twavObservationPrev.timestamp; } _twav = (_twavObservationCurrent.cumulativeValuation - _twavObservationPrev.cumulativeValuation) / _timeElapsed;

#0 - HardlyDifficult

2022-07-03T23:12:34Z

Findings Information

🌟 Selected for report: hansfriese

Labels

bug
2 (Med Risk)
sponsor confirmed

Awards

2339.3444 USDC - $2,339.34

External Links

Lines of code

https://github.com/code-423n4/2022-06-nibbl/blob/8c3dbd6adf350f35c58b31723d42117765644110/contracts/Twav/Twav.sol#L36

Vulnerability details

Impact

The "if" condition of Twav._getTwav() is missing some edge cases. In this case, this function will return 0 which is different from the correct value and it will affect the main functions like NibblVault.buy() and NibblVault.sell().

Proof of Concept

I think this condition is to confirm at least 4 values were saved for twav calculation. Btw this timestamp would be zero even though there are more than 4 values properly as it's modularized by 2**32. In this case, the if condition will be false and this function will return 0.

Tools Used

Solidity Visual Developer of VSCode

I see "cumulativeValuation" is increasing all the time and recommend replacing "timestamp" with "cumulativeValuation".

if (twavObservations[TWAV_BLOCK_NUMBERS - 1].cumulativeValuation != 0) {

#0 - mundhrakeshav

2022-07-01T07:59:21Z

#1 - HardlyDifficult

2022-07-03T23:14:44Z

Interesting catch. This is related to #178 but presents a distinct issue.

#0 - HardlyDifficult

2022-07-04T16:06:18Z

Merging with https://github.com/code-423n4/2022-06-nibbl-findings/issues/110

Relevant improvements suggested, mostly NC.

  1. Use != 0 instead of > 0 for uint variables
  1. No need to initialize variables with default values
  1. Use ++i instead of i++, i+=1, also unchecked increments in for-loops will save gas cost
  1. An array’s length should be cached to save gas in for-loops
  1. Non-strict inequalities are cheaper than strict ones
  1. Usage of unchecked can reduce the gas cost
  1. require()/revert() strings longer than 32 bytes cost extra gas
  1. Check zero amount before transfer
  1. Check "_feeAdmin != 0" instead of "_adminFeeAmt > 0". The real transfer amount is _feeAdmin and this value might be zero even though _adminFeeAmt > 0 according to fee calculation
  1. Needless calculation From the calculation, we can see "(_index + 1) % TWAV_BLOCK_NUMBERS" is same as "twavObservationsIndex" because "_index" is the previous index of "twavObservationsIndex".
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