# UniswapFlashloanBalancerSwapHandler

[Git Source](https://github.com/Ion-Protocol/ion-protocol/blob/88cc595825f1dc2eb738fb93e172a3e8ab7a5c43/src/flash/UniswapFlashloanBalancerSwapHandler.sol)

**Inherits:** IUniswapV3FlashCallback, IonHandlerBase

This contract allows for easy creation and closing of leverage positions through Uniswap flashloans and LST swaps on Balancer. In terms of creation, this may be a more desirable path than directly minting from an LST provider since market prices tend to be slightly lower than provider exchange rates. DEXes also provide an avenue for atomic deleveraging since the LST -> ETH exchange can be made. NOTE: Uniswap flashloans do charge a small fee.

*Some tokens only have liquidity on Balancer. Due to the reentrancy lock on the Balancer VAULT, utilizing their free flashloan followed by a pool swap is not possible. Instead, we will take a cheap (0.01%) flashloan from the wstETH/ETH uniswap pool and perform the Balancer swap. The rETH/ETH uniswap pool could also be used since it has a 0.01% fee but it does have less liquidity.*

### [State Variables](https://docs.ionprotocol.io/devs/smart-contract-architecture/flash/broken-reference) <a href="#state-variables" id="state-variables"></a>

#### [VAULT](https://docs.ionprotocol.io/devs/smart-contract-architecture/flash/broken-reference) <a href="#vault" id="vault"></a>

```
IVault internal constant VAULT = IVault(0xBA12222222228d8Ba445958a75a0704d566BF2C8);
```

#### [WETH\_IS\_TOKEN0\_ON\_UNISWAP](https://docs.ionprotocol.io/devs/smart-contract-architecture/flash/broken-reference) <a href="#weth_is_token0_on_uniswap" id="weth_is_token0_on_uniswap"></a>

```
bool immutable WETH_IS_TOKEN0_ON_UNISWAP;
```

#### [FLASHLOAN\_POOL](https://docs.ionprotocol.io/devs/smart-contract-architecture/flash/broken-reference) <a href="#flashloan_pool" id="flashloan_pool"></a>

```
IUniswapV3Pool public immutable FLASHLOAN_POOL;
```

#### [BALANCER\_POOL\_ID](https://docs.ionprotocol.io/devs/smart-contract-architecture/flash/broken-reference) <a href="#balancer_pool_id" id="balancer_pool_id"></a>

```
bytes32 public immutable BALANCER_POOL_ID;
```

### [Functions](https://docs.ionprotocol.io/devs/smart-contract-architecture/flash/broken-reference) <a href="#functions" id="functions"></a>

#### [constructor](https://docs.ionprotocol.io/devs/smart-contract-architecture/flash/broken-reference) <a href="#constructor" id="constructor"></a>

Creates a new instance of `UniswapFlashloanBalancerSwapHandler`

```
constructor(IUniswapV3Pool _flashloanPool, bytes32 _balancerPoolId);
```

**Parameters**

| Name              | Type             | Description                                            |
| ----------------- | ---------------- | ------------------------------------------------------ |
| `_flashloanPool`  | `IUniswapV3Pool` | UniswapV3 pool from which to flashloan                 |
| `_balancerPoolId` | `bytes32`        | Balancer pool identifier through which to route swaps. |

#### [flashLeverageWethAndSwap](https://docs.ionprotocol.io/devs/smart-contract-architecture/flash/broken-reference) <a href="#flashleveragewethandswap" id="flashleveragewethandswap"></a>

Transfer collateral from user + flashloan WETH from Uniswap -> swap for collateral using WETH on Balancer pool -> deposit all collateral into `IonPool` -> borrow WETH from `IonPool` -> repay Uniswap flashloan + fee. Uniswap flashloans do incur a fee.

```
function flashLeverageWethAndSwap(
    uint256 initialDeposit,
    uint256 resultingAdditionalCollateral,
    uint256 maxResultingAdditionalDebt,
    uint256 deadline,
    bytes32[] calldata proof
)
    external
    payable
    checkDeadline(deadline)
    onlyWhitelistedBorrowers(proof);
```

**Parameters**

| Name                            | Type        | Description                                                                                                                       |
| ------------------------------- | ----------- | --------------------------------------------------------------------------------------------------------------------------------- |
| `initialDeposit`                | `uint256`   | in collateral terms. \[WAD]                                                                                                       |
| `resultingAdditionalCollateral` | `uint256`   | in collateral terms. \[WAD]                                                                                                       |
| `maxResultingAdditionalDebt`    | `uint256`   | in WETH terms. This value also allows the user to control slippage of the swap. \[WAD]                                            |
| `deadline`                      | `uint256`   | timestamp for which the transaction must be executed. This prevents txs that have sat in the mempool for too long to be executed. |
| `proof`                         | `bytes32[]` | used to validate the user is whitelisted.                                                                                         |

#### [flashDeleverageWethAndSwap](https://docs.ionprotocol.io/devs/smart-contract-architecture/flash/broken-reference) <a href="#flashdeleveragewethandswap" id="flashdeleveragewethandswap"></a>

Flashloan WETH from Uniswap -> repay debt in `IonPool` -> withdraw collateral from `IonPool` -> sell collateral for `WETH` on Balancer -> repay Uniswap flashloan + fee. Uniswap flashloans do incur a fee.

```
function flashDeleverageWethAndSwap(
    uint256 maxCollateralToRemove,
    uint256 debtToRemove,
    uint256 deadline
)
    external
    checkDeadline(deadline);
```

**Parameters**

| Name                    | Type      | Description                                                                                                                       |
| ----------------------- | --------- | --------------------------------------------------------------------------------------------------------------------------------- |
| `maxCollateralToRemove` | `uint256` | The max amount of collateral user is willing to sell to repay `debtToRemove` debt. \[WAD]                                         |
| `debtToRemove`          | `uint256` | The desired amount of debt to remove. \[WAD]                                                                                      |
| `deadline`              | `uint256` | timestamp for which the transaction must be executed. This prevents txs that have sat in the mempool for too long to be executed. |

#### [uniswapV3FlashCallback](https://docs.ionprotocol.io/devs/smart-contract-architecture/flash/broken-reference) <a href="#uniswapv3flashcallback" id="uniswapv3flashcallback"></a>

Called to `msg.sender` after transferring to the recipient from IUniswapV3Pool#flash.

*In the implementation, you must repay the pool the tokens sent by `flash()` plus the computed fee amounts. The caller of this method must be checked to be a UniswapV3Pool. Initiator is guaranteed to be this contract since UniswapV3 pools will only call the callback on msg.sender.*

```
function uniswapV3FlashCallback(uint256 fee0, uint256 fee1, bytes calldata data) external override;
```

**Parameters**

| Name   | Type      | Description                                                                    |
| ------ | --------- | ------------------------------------------------------------------------------ |
| `fee0` | `uint256` | The fee amount in tokenInBalancer due to the pool by the end of the flash      |
| `fee1` | `uint256` | The fee amount in tokenOutBalancer due to the pool by the end of the flash     |
| `data` | `bytes`   | Any data passed through by the caller via the IUniswapV3PoolActions#flash call |

#### [\_simulateGivenOutBalancerSwap](https://docs.ionprotocol.io/devs/smart-contract-architecture/flash/broken-reference) <a href="#simulategivenoutbalancerswap" id="simulategivenoutbalancerswap"></a>

Simulates a Balancer swap with a desired amount of `assetOut`.

```
function _simulateGivenOutBalancerSwap(
    IVault.FundManagement memory fundManagement,
    address assetIn,
    address assetOut,
    uint256 amountOut
)
    internal
    returns (uint256);
```

**Parameters**

| Name             | Type                    | Description                                                     |
| ---------------- | ----------------------- | --------------------------------------------------------------- |
| `fundManagement` | `IVault.FundManagement` | Balancer fund management struct                                 |
| `assetIn`        | `address`               | asset to swap from                                              |
| `assetOut`       | `address`               | asset to swap to                                                |
| `amountOut`      | `uint256`               | desired amount of assetOut. Will revert if not received. \[WAD] |

### [Errors](https://docs.ionprotocol.io/devs/smart-contract-architecture/flash/broken-reference) <a href="#errors" id="errors"></a>

#### [WethNotInPoolPair](https://docs.ionprotocol.io/devs/smart-contract-architecture/flash/broken-reference) <a href="#wethnotinpoolpair" id="wethnotinpoolpair"></a>

```
error WethNotInPoolPair(IUniswapV3Pool pool);
```

#### [ReceiveCallerNotPool](https://docs.ionprotocol.io/devs/smart-contract-architecture/flash/broken-reference) <a href="#receivecallernotpool" id="receivecallernotpool"></a>

```
error ReceiveCallerNotPool(address unauthorizedCaller);
```

### [Structs](https://docs.ionprotocol.io/devs/smart-contract-architecture/flash/broken-reference) <a href="#structs" id="structs"></a>

#### [FlashCallbackData](https://docs.ionprotocol.io/devs/smart-contract-architecture/flash/broken-reference) <a href="#flashcallbackdata" id="flashcallbackdata"></a>

```
struct FlashCallbackData {
    address user;
    uint256 initialDeposit;
    uint256 maxResultingAdditionalDebtOrCollateralToRemove;
    uint256 wethFlashloaned;
    uint256 amountToLeverage;
}
```
