Lucene search

K
code423n4Code4renaCODE423N4:2022-12-ESCHER-FINDINGS-ISSUES-472
HistoryDec 09, 2022 - 12:00 a.m.

Ether can be lost in LPDA contract if sale.dropPerSecond is set improperly

2022-12-0900:00:00
Code4rena
github.com
3
vulnerability
lpda contract
ether loss

Lines of code
<https://github.com/code-423n4/2022-12-escher/blob/main/src/minters/LPDA.sol#L143&gt;
<https://github.com/code-423n4/2022-12-escher/blob/main/src/minters/LPDA.sol#L63&gt;
<https://github.com/code-423n4/2022-12-escher/blob/main/src/minters/LPDA.sol#L101&gt;

Vulnerability details

Impact

Function createLPDASale() requires only sale.dropPerSecond > 0 but if sale.dropPerSecond > sale.startPrice / (sale.endTime - sale.startTime) function getPrice() will revert (except the case when all editions are sold before reaching negative price). Therefore, the buy() and refund() functions will also become unavailable – Creator will no longer be able to sell and all their Ether (and fees) will be locked in the contract, and users will not be able to refund, so they will also lose Ether. The dropPerSecond value can be set too high (an extra zero or something) and this must be prevented to avoid losing assets.

Proof of Concept

For example, at the start of the sale:
uint96 startTime = 120
uint96 endTime = 300
uint80 startPrice = 50,000
uint80 dropPerSecond = 300

At the time = 290 (if not all editions are sold), the price will be calculated as:

uint256 timeElapsed = end &gt; block.timestamp ? block.timestamp - start : end - start;
return temp.startPrice - (temp.dropPerSecond * timeElapsed);

So, timeElapsed = 290 - 120 = 170,
return 50,000 - (300*170) = -1000 => the function getPrice() reverts.

Tools Used

Manual review.

Recommended Mitigation Steps

Add the check in the function createLPDASale():

require(sale.dropPerSecond &lt; sale.startPrice / (sale.endTime - sale.startTime) , "INVALID DROP PER SECOND");

The text was updated successfully, but these errors were encountered:

All reactions