# Transferring quoteToken to the exchange pool contract will cause future liquidity providers to lose funds

ElasticSwap addLiquidity() priced LP tokens off the pool's raw quoteToken balance, so an attacker donating quoteToken inflated the reserve and diluted later LPs' shares.

- Payout: Audit contest
- Severity: high
- Program: ElasticSwap
- Found by: WatchPug
- Disclosed: 2022-03-02
- Write-up quality: 7/10
- Original: https://github.com/code-423n4/2022-01-elasticswap-findings/issues/146
- Library page: https://bugbountylibrary.com/r/c4%3A2022-01-elasticswap%3AH-02
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:high tech:evm tech:solidity technique:source-review vuln:accounting-error vuln:share-inflation

**Target:** Exchange pool addLiquidity/removeLiquidity LP-token accounting
**Root cause:** LP token quantity for double-asset entry is computed from IERC20(quoteToken).balanceOf(address(this)) instead of the tracked _internalBalances.quoteTokenReserveQty, so unsolicited transfers inflate the reserve ratio used for minting.
**Steps:**
1. Deploy fresh Exchange pool; Alice addLiquidity(1e18 baseToken, 1e18 quoteToken) -> receives 1e18 LP.
2. Alice transfers 99e18 quoteToken directly to the Exchange contract, raising balanceOf above quoteTokenReserveQty.
3. Bob addLiquidity(1e18 baseToken, 1e18 quoteToken); minting uses inflated quote reserve so Bob gets far fewer LP tokens.
4. Bob removeLiquidity(all LP) -> receives ~0.02e18 baseToken and ~1e18 quoteToken.
5. Alice removeLiquidity() -> receives ~1.98e18 baseToken and ~100e18 quoteToken, netting Bob's 0.98e18 baseToken.
**How found:** Code review of MathLib.calculateLiquidityTokenQtyForDoubleAssetEntry call site; noticed the reserve argument was the live token balance (per the inline comment) rather than the internal tracked reserve, making it manipulable by direct transfer.
**Exploitation:** Attacker seeds a pool, donates quoteToken directly to the contract to skew the balance-based ratio, lets a victim add liquidity at the distorted price, then withdraws to capture the victim's baseToken contribution.
**Insight:** When AMM math reads balanceOf() instead of an internally tracked reserve, any direct token transfer becomes a share-price manipulation primitive; check every reserve argument passed into mint/burn math for balance-vs-internal-balance mismatch.
