# ElasticSwap: internal balance manipulation drains $845k via flash loan

ElasticSwap's internal balance accounting was manipulated via addLiquidity/removeLiquidity and a huge swap, letting an attacker drain ~$845k of TIC/USDC.e.

- Payout: Real-world hack
- Severity: high
- Program: - ElasticSwap
- Analysis by: DeFiHackLabs
- Disclosed: 2022-12-13
- Write-up quality: 7/10
- Original: https://github.com/SunWeb3Sec/DeFiHackLabs/blob/main/src/test/2022-12/ElasticSwap_exp.sol
- Library page: http://bugbountylibrary.com/r/dhl%3A20221213-elasticswap
- Tags: area:web3 domain:web3 impact:funds-loss kind:incident platform:defihacklabs sev:high tech:evm tech:solidity technique:chained vuln:accounting-error vuln:business-logic vuln:oracle-manipulation

**Target:** ELPExchange AMM contract on Avalanche
**Root cause:** The exchange tracks internalBalances (baseTokenReserveQty, quoteTokenReserveQty, kLast) separately from actual token balances; addLiquidity/removeLiquidity and swapQuoteTokenForBaseToken let an attacker desync internal reserves from real balances, so a swap priced against a stale/manipulated quote reserve overpays base tokens.
**Steps:**
1. Flash-borrow 51,112 TIC from Trader Joe SPair via `SPair.swap(51_112 * 1e18, 0, address(this), new bytes(1))`.
2. In uniswapV2Call, flash-borrow 766,685 USDC.e from Joe JPair via `JPair.swap(766_685 * 1e6, 0, address(this), new bytes(1))`.
3. In joeCall, read ELP's TIC and USDC.e balances, then `ELP.addLiquidity(1e9, 0, 0, 0, address(this), ...)` and `ELP.addLiquidity(TICAmount, USDC_EAmount, 0, 0, address(this), ...)`.
4. Transfer all USDC.e to ELP, then `ELP.removeLiquidity(ELP.balanceOf(address(this)), 1, 1, address(this), ...)`.
5. Read `ELP.internalBalances()`, take quoteTokenReserveQty, and call `ELP.swapQuoteTokenForBaseToken(USDC_EReserve * 100, 1, ...)` to extract TIC at a manipulated price.
6. Re-add liquidity with the received TIC/USDC.e, remove it, and repay JPair `774_353 * 1e6` USDC.e; repay SPair with `TIC.transfer(address(SPair), 51_624 * 1e18)`.
7. Keep the residual TIC and USDC.e as profit.
**Exploitation:** Two nested flash loans (TIC from a Trader Joe pair, USDC.e from another) fund the attack. The attacker seeds and removes liquidity to desync ELP's internal reserve accounting, then swaps USDC.e for TIC at a quote reserve inflated 100x, extracting TIC cheaply, re-adds/removes liquidity to convert, and repays both flash loans leaving ~$845k profit.
**Escalation:** Chained two flash loans across Trader Joe pairs and repeated add/remove liquidity cycles to amplify the internal-balance desync before the oversized swap.
**Insight:** AMMs that track internal reserves separately from actual token balances (for 'decay'/elastic accounting) can be desynced by add/remove liquidity sequences; check whether swap pricing reads internalBalances that liquidity ops can skew before a large swap.

