FactoryDAO contest - WatchPug'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: 8/71

Findings: 2

Award: $1,823.44

🌟 Selected for report: 1

πŸš€ Solo Findings: 1

Findings Information

Awards

63.9296 DAI - $63.93

Labels

bug
duplicate
3 (High Risk)

External Links

Lines of code

https://github.com/code-423n4/2022-05-factorydao/blob/db415804c06143d8af6880bc4cda7222e5463c0e/contracts/FixedPricePassThruGate.sol#L46-L56

Vulnerability details

In FixedPricePassThruGate.sol#passThruGate(), at L48 the msg.value is checked to be >= gate.ethCost instead of == gate.ethCost, which makes it possible for the caller to send more than gate.ethCost.

However, at L53 only the amount of gate.ethCost is passed thru to gate.beneficiary instead of all the msg.value.

https://github.com/code-423n4/2022-05-factorydao/blob/db415804c06143d8af6880bc4cda7222e5463c0e/contracts/FixedPricePassThruGate.sol#L46-L56

function passThruGate(uint index, address) override external payable {
    Gate memory gate = gates[index];
    require(msg.value >= gate.ethCost, 'Please send more ETH');

    // pass thru 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: gate.ethCost}("");
        require(sent, 'ETH transfer failed');
    }
}

As a result, any surplus funds sent by the caller will be stuck in the contract forever, and there is no way for anyone to retrieve them.

Recommendation

Change to:

(bool sent, bytes memory data) = gate.beneficiary.call{value: msg.value}("");

See also: the implementation of SpeedBumpPriceGate.sol correctly forwarded all the msg.value.

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

function passThruGate(uint index, address) 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}("");
        require(sent, 'ETH transfer failed');
    }
}

#0 - illuzen

2022-05-11T09:47:16Z

Duplicate #49

#1 - gititGoro

2022-06-14T02:52:48Z

Upgrated severity: lost funds

#2 - gititGoro

2022-06-14T02:53:05Z

Duplicate of #48

Findings Information

🌟 Selected for report: WatchPug

Labels

bug
2 (Med Risk)
disagree with severity
sponsor acknowledged

Awards

1759.5116 DAI - $1,759.51

External Links

Lines of code

https://github.com/code-423n4/2022-05-factorydao/blob/db415804c06143d8af6880bc4cda7222e5463c0e/contracts/SpeedBumpPriceGate.sol#L43

Vulnerability details

https://github.com/code-423n4/2022-05-factorydao/blob/db415804c06143d8af6880bc4cda7222e5463c0e/contracts/SpeedBumpPriceGate.sol#L43

    gate.priceIncreaseDenominator = priceIncreaseDenominator;

If priceIncreaseDenominator is set to 0 when addGate(), in passThruGate() the tx will revert at L72 because of div by 0.

https://github.com/code-423n4/2022-05-factorydao/blob/db415804c06143d8af6880bc4cda7222e5463c0e/contracts/SpeedBumpPriceGate.sol#L71-L72

    // multiply by the price increase factor
    gate.lastPrice = (price * gate.priceIncreaseFactor) / gate.priceIncreaseDenominator;

Recommendation

Consider adding a check in addGate() to require priceIncreaseDenominator > 0.

#0 - illuzen

2022-05-11T09:45:40Z

This is fine, we just add another gate, redeploy the tree and only harm done is we lost some gas.

#1 - gititGoro

2022-06-17T02:49:09Z

While value is not leaked in this instance, this can cause functionality to be interrupted until fixed. Severity of issue will be maintained.

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