# LPDA price can underflow the price due to bad settings and potentially brick the contract

LPDA dutch auction getPrice underflows when dropPerSecond*timeElapsed exceeds startPrice, reverting buy and bricking the sale permanently.

- Payout: Contest reward
- Severity: high
- Program: Escher
- Credited: adriro
- Disclosed: 2023-02-22
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2022-12-escher-findings/issues/392
- Library page: https://bugbountylibrary.com/r/c4%3A2022-12-escher%3AH-02
- Tags: domain:web3 impact:dos impact:funds-loss kind:contest platform:code4rena sev:high tech:evm tech:solidity technique:source-review vuln:accounting-error vuln:dos

**Target:** LPDA dutch auction minter contract (Solidity)
**Root cause:** getPrice computes startPrice - (dropPerSecond * timeElapsed) with no cap; if the product exceeds startPrice, Solidity 0.8 checked math reverts. Factory never validates that duration*dropPerSecond <= startPrice.
**Steps:**
1. Deploy LPDA sale with startPrice=1500, dropPerSecond=1, duration=3600s
2. Warp to startTime + 1800s (drop*elapsed=1800 > 1500)
3. Call `getPrice()` -> reverts on underflow
4. Call `buy{value: price*amount}(amount)` -> reverts since it calls getPrice
**How found:** Code review of getPrice arithmetic: noticed unchecked subtraction of a monotonically growing drop term against a fixed startPrice, and that factory lacked bounds validation on dropPerSecond vs duration.
**Exploitation:** No attacker action needed; misconfigured sale self-bricks as time elapses. Buyers can never purchase, so the sale can never reach finalId and funds are never transferred to saleReceiver.
**Insight:** In descending-price auctions, always check that the maximum cumulative discount (rate * full duration) cannot exceed the initial price; validate at factory/creation time, not just at read time.
