# Users who deposited MIM and USDB tokens into BlastOnboarding may incur losses when the pool is created via bootstrap

Imbalanced MIM/USDB deposits in BlastOnboarding create a MagicLP pool where quote target < reserve, letting an attacker sell quote then base to drain ~158 MIM.

- Payout: Contest reward
- Severity: high
- Program: Abracadabra Money
- Credited: ether\_sky
- Disclosed: 2024-05-03
- Write-up quality: 8/10
- Original: https://github.com/code-423n4/2024-03-abracadabra-money-findings/issues/76
- Library page: https://bugbountylibrary.com/r/c4%3A2024-03-abracadabra-money%3AH-03
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:high tech:evm tech:solidity technique:source-review vuln:business-logic vuln:oracle-manipulation

**Target:** BlastOnboarding / Router.createPool / MagicLP buyShares
**Root cause:** buyShares sets targets as min(base, quote*I) but reserves keep full deposited amounts, so when locked MIM and USDB amounts differ, one token's target is below its reserve. This mispricing lets an attacker profit by selling the excess token then the other.
**Steps:**
1. BlastOnboarding locks 1000 MIM and 3000 USDB; bootstrap calls `router.createPool(MIM, USDB, FEE_RATE, I, K, address(this), 1000e18, 3000e18)`.
2. Pool state: base reserve 1000, base target 1000, quote reserve 3000, quote target 1000 (target < reserve for quote).
3. Attacker calls `router.sellQuoteTokensForTokens(pool, bob, 1000e18, 0, max)` selling 1000 USDB; state becomes ABOVE_ONE with base reserve ~21.97, quote reserve 4000.
4. Attacker reads `lp.getPMMState()`; adjusted base target B0 ~2841.09.
5. Attacker calls `router.sellBaseTokensForTokens(pool, bob, B0 - B, 0, max)` selling ~2819 MIM for ~3000 USDB.
6. Net profit ~158 MIM; protocol/users lose equivalent value.
**How found:** Researcher noticed bootstrap uses all locked MIM and USDB without ensuring equal amounts, and that Router.createPool calls buyShares which sets targets to min(base, quote*I) while reserves remain full. They hypothesized that target < reserve for one token creates a mispricing exploitable via sequential sells, then confirmed with a Foundry test showing 158 MIM profit.
**Exploitation:** Attacker needs only capital to sell quote tokens into the freshly bootstrapped pool. By selling 1000 USDB first, they push the pool into ABOVE_ONE state where the adjusted base target becomes large (~2841). Then they sell base tokens up to the adjusted target, receiving quote at an inflated price. The imbalance between locked MIM and USDB amounts (which bootstrap cannot avoid) is the precondition; no flash loan needed, just the ability to trade against the pool before others.
**Insight:** When a pool is initialized with two assets of nominally equal price but unequal amounts, check whether the AMM's target/reserve invariant is broken. If targets are set to the minimum of the two sides, the larger side's reserve exceeds its target, creating an arbitrage: sell the excess side to flip the state, then sell the other side at the inflated adjusted target.
