code-423n4 / 2022-12-escher-findings

0 stars 0 forks source link

Creators of LPDA auctions cannot withdraw funds if auction doesn't sell out at final price #89

Closed code423n4 closed 1 year ago

code423n4 commented 1 year ago

Lines of code

https://github.com/code-423n4/2022-12-escher/blob/5d8be6aa0e8634fdb2f328b99076b0d05fefab73/src/minters/LPDA.sol#L81-L88

Vulnerability details

Impact

In an LPDA auction, the price falls from startPrice down to startPrice - (dropPerSecond * (endTime - startTime). At this point, the auction continues, but the price no longer falls.

If the auction stops at a price that doesn't clear the market, it'll remain open indefinitely.

But, as long as the auction remains open, the owners are not able to withdraw their funds and the feeReceiver doesn't receive their fees.

The result is that an NFT collection can be mostly minted and active, but the owners are not able to collect their earnings to fund the project.

Proof of Concept

The only place in the LPDA.sol contract where funds are transferred to the feeReceiver and saleReceiver are in the final block of the buy() function:

if (newId == temp.finalId) {
    sale.finalPrice = uint80(price);
    uint256 totalSale = price * amountSold;
    uint256 fee = totalSale / 20;
    ISaleFactory(factory).feeReceiver().transfer(fee);
    temp.saleReceiver.transfer(totalSale - fee);
    _end();
}

For this block to execute, the NFTs need to be minted up to the point where newId == sale.finalId. If this doesn't happen, this block can never execute.

There are only two ways for this to happen:

1) cancel() is called, which can only happen before a sale starts. 2) Enough NFTs are minted that currentId increases to the point that currentId + amount reaches finalId.

If the latter doesn't happen, the funds will be stuck.

[Note that this doesn't impact refunds, as users will be able to call refund() at any time to get their refund up to the current price.]

Tools Used

Manual Review

Recommended Mitigation Steps

Add an end() function that can be called after the endTime to finalize the LPDA and process the payouts.

c4-judge commented 1 year ago

berndartmueller marked the issue as duplicate of #328

c4-judge commented 1 year ago

berndartmueller changed the severity to 2 (Med Risk)

c4-judge commented 1 year ago

berndartmueller marked the issue as satisfactory