# Dutch auction can be manipulated

Buying all but 1 wei of Dutch auction commitments blocks _endAuction, forcing price to decay so attacker buys arb tokens at steep discount.

- Payout: Audit contest
- Severity: medium
- Program: Malt Finance
- Found by: gzeon
- Disclosed: 2022-02-14
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2021-11-malt-findings/issues/375
- Library page: https://bugbountylibrary.com/r/c4%3A2021-11-malt%3AM-26
- Tags: area:web3 domain:web3 impact:funds-loss kind:contest platform:code4rena sev:medium tech:evm tech:solidity technique:source-review vuln:accounting-error vuln:business-logic

**Target:** Auction.sol Dutch auction / StabilizerNode stabilize()
**Root cause:** Auction only finalizes when commitments >= maxCommitments or via stabilize(); leaving 1 wei unfilled blocks finalization because purchasing 1 wei reverts in AMM swap (INSUFFICIENT_AMOUNT), and stabilize() is delayed by stabilizeBackoffPeriod with no incentive to call it.
**Steps:**
1. Call `purchaseArbitrageTokens` for `auction.maxCommitments - 1 wei` so `auction.commitments < auction.maxCommitments` and `_endAuction()` is not triggered.
2. Further purchases revert because `purchaseAndBurn` swaps 1 wei and AMM returns amountOut==0 (INSUFFICIENT_AMOUNT).
3. Auction cannot finalize until `stabilize()` is callable, which requires `block.timestamp >= stabilizeWindowEnd` (stabilizeBackoffPeriod ~5 min).
4. Wait for price to decay toward endprice (auctionLength ~10 min), then buy at (startingPrice+endingPrice)/2 or lower.
**How found:** Code reading of Auction.sol finalization conditions and StabilizerNode stabilize() gating; noticed the 1-wei gap prevents _endAuction and that AMM rounding reverts tiny swaps, plus no incentive to call stabilize().
**Exploitation:** Attacker front-runs to fill all but 1 wei of commitments, freezing auction finalization; price decays linearly toward endprice during the stabilize backoff window, letting attacker purchase arb tokens at a guaranteed ~50% discount versus start price.
**Insight:** When an auction/vesting finalizes on a threshold (maxCommitments) or a permissionless trigger with a time backoff, check whether an attacker can park state just below the threshold and whether the trigger has any caller incentive; AMM rounding reverts on dust amounts are a reliable way to make the last unit unbuyable.
