Nibbl contest - cccz'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: 8/96

Findings: 3

Award: $1,312.51

🌟 Selected for report: 1

πŸš€ Solo Findings: 0

Findings Information

🌟 Selected for report: cccz

Also found by: Lambda, WatchPug, kenzo, xiaoming90, zzzitron

Labels

bug
2 (Med Risk)
disagree with severity
sponsor acknowledged

Awards

230.2266 USDC - $230.23

External Links

Lines of code

https://github.com/code-423n4/2022-06-nibbl/blob/8c3dbd6adf350f35c58b31723d42117765644110/contracts/NibblVault.sol#L314-L323

Vulnerability details

Impact

In the buy function of the NibblVault contract, when msg.value > _lowerCurveDiff, the fee for SecondaryCurve part is not charged.

if (_lowerCurveDiff >= msg.value) { _purchaseReturn = _buySecondaryCurve(msg.value, _totalSupply); } else { //Gas Optimization _purchaseReturn = _initialTokenSupply - _totalSupply; secondaryReserveBalance += _lowerCurveDiff; // _purchaseReturn = _buySecondaryCurve(_to, _lowerCurveDiff); _purchaseReturn += _buyPrimaryCurve(msg.value - _lowerCurveDiff, _totalSupply + _purchaseReturn); }

Proof of Concept

https://github.com/code-423n4/2022-06-nibbl/blob/8c3dbd6adf350f35c58b31723d42117765644110/contracts/NibblVault.sol#L314-L323

Tools Used

None

The fee for the SecondaryCurve part is complex to charge. I implemented the _caculateFeeSecondaryCurve and _reverseFeeSecondaryCurve functions to do the relevant calculations. The _caculateFeeSecondaryCurve function is used to calculate the value after the fee is charged, but not to actually charge the fee. The _reverseFeeSecondaryCurve function is used to calculate the value before the fee is charged.

if (_lowerCurveDiff >= _caculateFeeSecondaryCurve(msg.value)) { _purchaseReturn = _buySecondaryCurve(msg.value, _totalSupply); } else { //Gas Optimization _purchaseReturn = _initialTokenSupply - _totalSupply; secondaryReserveBalance += _lowerCurveDiff; uint256 _amount = _reverseFeeSecondaryCurve(_lowerCurveDiff); _chargeFeeSecondaryCurve(_amount); // _purchaseReturn = _buySecondaryCurve(_to, _lowerCurveDiff); _purchaseReturn += _buyPrimaryCurve(msg.value - _amount, _totalSupply + _purchaseReturn); }
function _caculateFeeSecondaryCurve(uint256 _amount) private returns(uint256) { address payable _factory = factory; uint256 _adminFeeAmt = NibblVaultFactory(_factory).feeAdmin(); uint256 _feeAdmin = (_amount * _adminFeeAmt) / SCALE ; uint256 _feeCurator = (_amount * curatorFee) / SCALE ; return _amount - (_feeAdmin + _feeCurator); } function _reverseFeeSecondaryCurve(uint256 _amount) private returns(uint256) { address payable _factory = factory; uint256 _adminFeeAmt = NibblVaultFactory(_factory).feeAdmin(); return _amount * SCALE / (SCALE - (_adminFeeAmt + curatorFee)); }

#0 - HardlyDifficult

2022-07-03T15:48:31Z

Failing to collect fees is a form of leaking value for the curator and therefore falls into the Medium risk definition -- keeping the severity as reported.

Findings Information

🌟 Selected for report: Picodes

Also found by: cccz

Labels

bug
duplicate
2 (Med Risk)
sponsor confirmed

Awards

1052.705 USDC - $1,052.70

External Links

Lines of code

https://github.com/code-423n4/2022-06-nibbl/blob/8c3dbd6adf350f35c58b31723d42117765644110/contracts/Basket.sol#L6-L7

Vulnerability details

Impact

Basket contracts are deployed using a proxy, but Basket inherits a non-upgradable version of the ERC721 contract, which makes it impossible to set the contract's name and symbol.

constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; }

Proof of Concept

https://github.com/code-423n4/2022-06-nibbl/blob/8c3dbd6adf350f35c58b31723d42117765644110/contracts/Basket.sol#L6-L7 https://github.com/code-423n4/2022-06-nibbl/blob/8c3dbd6adf350f35c58b31723d42117765644110/contracts/Basket.sol#L13-L14 https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/ERC721.sol#L44-L47

Tools Used

None

Using upgradable version of the ERC721 contract https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/blob/master/contracts/token/ERC721/ERC721Upgradeable.sol

#0 - mundhrakeshav

2022-06-30T09:17:24Z

#1 - HardlyDifficult

2022-07-03T16:17:01Z

Confirmed this is an issue.

Assets are not at risk, and the function of the protocol is not impacted. All baskets created will have an empty name/symbol but generally there is no requirement that these values are populated. It's mostly for a better experience on frontends including etherscan. Downgrading and merging with the warden's QA report #160

#2 - HardlyDifficult

2022-07-05T19:44:26Z

Lines of code

https://github.com/code-423n4/2022-06-nibbl/blob/8c3dbd6adf350f35c58b31723d42117765644110/contracts/NibblVault.sol#L414-L417

Vulnerability details

Impact

In the initiateBuyout function of the NibblVault contract, the second parameter of the BuyoutInitiated event is _buyoutBid instead of _currentValuation, and since the excess Ether in _buyoutBid is transferred to the user, the actual buyout price for the user is the _currentValuation variable. The user can use a large amount of Ether to get a large _buyoutBid variable, however the actual amount of Ether spent by the user is _currentValuation. Events emitted by the smart contract are used off-chain, and incorrect event parameters may have an impact on the user's trading behavior

Proof of Concept

https://github.com/code-423n4/2022-06-nibbl/blob/8c3dbd6adf350f35c58b31723d42117765644110/contracts/NibblVault.sol#L414-L417

Tools Used

None

- emit BuyoutInitiated(msg.sender, _buyoutBid); + emit BuyoutInitiated(msg.sender, _currentValuation);

#0 - HardlyDifficult

2022-07-03T16:05:05Z

Agree. However issues with events falls into the non-critical definition: "off-chain monitoring (events, etc)". Downgrading and converting this into a QA report for the warden.

#1 - HardlyDifficult

2022-07-03T16:12:38Z

#2 - HardlyDifficult

2022-07-03T16:15:48Z

#3 - HardlyDifficult

2022-07-03T16:20:07Z

#4 - HardlyDifficult

2022-07-04T15:34:20Z

Good low risk & best practice suggestions.

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