FactoryDAO contest - cccz's results

The DAO that builds DAOs.

General Information

Platform: Code4rena

Start Date: 04/05/2022

Pot Size: $50,000 DAI

Total HM: 24

Participants: 71

Period: 5 days

Judge: Justin Goro

Total Solo HM: 14

Id: 119

League: ETH

FactoryDAO

Findings Distribution

Researcher Performance

Rank: 56/71

Findings: 2

Award: $67.11

🌟 Selected for report: 1

πŸš€ Solo Findings: 0

Findings Information

Awards

63.9296 DAI - $63.93

Labels

bug
3 (High Risk)
disagree with severity
sponsor confirmed

External Links

Lines of code

https://github.com/code-423n4/2022-05-factorydao/blob/e22a562c01c533b8765229387894cc0cb9bed116/contracts/SpeedBumpPriceGate.sol#L65-L82

Vulnerability details

Impact

The passThruGate function of the SpeedBumpPriceGate contract is used to charge NFT purchase fees. Since the price of NFT will change due to the previous purchase, users are likely to send more ether than the actual purchase price in order to ensure that they can purchase NFT. However, the passThruGate function did not return the excess ether, which would cause asset loss to the user. Consider the following scenario:

  1. An NFT is sold for 0.15 eth
  2. User A believes that the value of the NFT is acceptable within 0.3 eth, considering that someone may buy the NFT before him, so user A transfers 0.3 eth to buy the NFT
  3. When user A's transaction is executed, the price of the NFT is 0.15 eth, but since the contract does not return excess eth, user A actually spends 0.3 eth.

Proof of Concept

https://github.com/code-423n4/2022-05-factorydao/blob/e22a562c01c533b8765229387894cc0cb9bed116/contracts/SpeedBumpPriceGate.sol#L65-L82

Tools Used

None

- function passThruGate(uint index, address) override external payable { + function passThruGate(uint index, address payer) override external payable { uint price = getCost(index); require(msg.value >= price, 'Please send more ETH'); // bump up the price Gate storage gate = gates[index]; // multiply by the price increase factor gate.lastPrice = (price * gate.priceIncreaseFactor) / gate.priceIncreaseDenominator; // move up the reference gate.lastPurchaseBlock = block.number; // pass thru the ether if (msg.value > 0) { // use .call so we can send to contracts, for example gnosis safe, re-entrance is not a threat here - (bool sent, bytes memory data) = gate.beneficiary.call{value: msg.value}(""); + (bool sent, bytes memory data) = gate.beneficiary.call{value: price}(""); require(sent, 'ETH transfer failed'); } + if (msg.value - price > 0){ + (bool sent, bytes memory data) = payer.call{value: msg.value - price}(""); + require(sent, 'ETH transfer failed');} }

#0 - illuzen

2022-05-10T07:01:08Z

Valid

#2 - gititGoro

2022-06-14T02:42:31Z

Maintaining severity as user funds are lost.

Awards

3.1753 DAI - $3.18

Labels

bug
duplicate
2 (Med Risk)

External Links

#0 - illuzen

2022-05-10T07:12:17Z

Duplicate

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