# PostAuctionLauncher.sol#finalize() Adding liquidity to an existing pool may allows the attacker to steal most of the tokens

PostAuctionLauncher.finalize() mints LP into any existing pair at auction-derived amounts, letting an attacker pre-seed a skewed pool and drain most auction tokens.

- Payout: Audit contest
- Severity: high
- Program: Sushi
- Found by: WatchPug
- Disclosed: 2021-11-05
- Write-up quality: 7/10
- Original: https://github.com/code-423n4/2021-09-sushimiso-findings/issues/14
- Library page: https://bugbountylibrary.com/r/c4%3A2021-09-sushimiso%3AH-01
- Tags: area:web3 domain:web3 impact:funds-loss kind:contest platform:code4rena sev:high tech:evm tech:solidity technique:chained technique:source-review vuln:business-logic vuln:oracle-manipulation

**Target:** PostAuctionLauncher.finalize() liquidity provisioning to UniswapV2 pair
**Root cause:** finalize() transfers auction token amounts and mints LP against whatever pair exists, ignoring current reserves/price, so minted LP is computed from a manipulated ratio.
**Steps:**
1. Attacker calls factory/createPool to create token1/token2 pair with tiny token1 (0.0000001) and 1000 token2, receiving ~0.01 LP.
2. Attacker calls `PostAuctionLauncher.finalize()`; contract transfers e.g. 2000 token1 and 1000 token2 to the pair and mints LP via `IUniswapV2Pair.mint`, receiving only ~0.01 LP due to `min(amount0*totalSupply/reserve0, amount1*totalSupply/reserve1)`.
3. Attacker removes all LP, receiving ~1000 token1 (mostly the launcher's tokens).
**How found:** Code review of finalize(): noticed it only calls createPool() when pair==address(0) and otherwise mints directly into an existing pair without checking reserves/price.
**Exploitation:** Pre-create the pair with a skewed reserve ratio, then trigger permissionless finalize() so the launcher's tokens are added at the unfair price; redeem LP to extract the launcher's token1.
**Insight:** When a contract mints LP into a pair it does not exclusively control, check whether it validates the pair's existing reserves; a permissionless finalize plus attacker-seeded pool lets the min() formula shortchange the protocol.

