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

0 stars 0 forks source link

Seller of LPDA can get more ETH than actually deserves #411

Closed code423n4 closed 1 year ago

code423n4 commented 1 year ago

Lines of code

https://github.com/code-423n4/2022-12-escher/blob/main/src/minters/LPDA.sol#L58-L89

Vulnerability details

Impact

The seller of LPDA get more ETH and buyers lose these ETH.

Proof of Concept

LPDA is used for a Last Price Dutch Auction Sale.

When the finalId is bought, the final price is set and totalSale = price * amountSold will be tranferred to feeReceiver and saleReceiver.

After that, there are still ETHs left in the contract because most users bid higher than the final price and they need to manually call refund to get the extra ETHs back.

If someone try to buy 0 NFT now (calls buy(0)), the function will assume that the sale is now complete and transfer ETHs to the feeReceiver and saleReceiver again. The buy(0) can be This operation be repeated until there is not 0 ETH in the contract.

Sample of a sale (total 40 NFTs) and attack:

Step Action LPDA saleReceiver feeReceiver
1 Buy 10 NFTs, price 1 ETH 10 ETH 0 ETH 0 ETH
2 Buy 10 NFTs, price 0.5 ETH 15 ETH 0 ETH 0 ETH
3 Buy 10 NFTs, price 0.2 ETH 17 ETH 0 ETH 0 ETH
4 Buy last 10 NFTs, price 0.1 ETH 14 ETH 3.8 ETH 0.2 ETH
5 Buy 0 10 ETH 7.6 ETH 0.4 ETH
6 Buy 0 6 ETH 11.4 ETH 0.6 ETH
7 Buy 0 2 ETH 15.2 ETH 0.8 ETH
8 Send 2 ETH to LPDA 4 ETH 15.2 ETH 0.8 ETH
9 Buy 0 0 ETH 19.0 ETH 1.0 ETH

Tools Used

Manual

Recommended Mitigation Steps

Check the _amount in buy(uint256 _amount).

require(_amount > 0, "INVALID AMOUNT");
c4-judge commented 1 year ago

berndartmueller marked the issue as duplicate of #16

c4-judge commented 1 year ago

berndartmueller marked the issue as satisfactory

C4-Staff commented 1 year ago

JeeberC4 marked the issue as duplicate of #441