# BalancerFlashloanDirectMintHandler

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

**Inherits:** IonHandlerBase, IFlashLoanRecipient

This contract allows for easy creation of leverage positions through Balancer flashloans and LST mints through the LST provider.

*There are a couple things to consider here from a security perspective. The first one is that the flashloan callback must only be callable from the Balancer vault. This ensures that nobody can pass arbitrary data to the callback. The second one is that the flashloan must only be initialized from this contract. This is a trickier one to enforce since Balancer flashloans are not EIP-3156 compliant and do not pass on the initiator through the callback. To get around this, an inverse reentrancy lock of sorts is used. The lock is set to 2 when a flashloan is initiated and set to 1 once the callback execution terminates. If the lock is not 2 when the callback is called, then the flashloan was not initiated by this contract and the tx is reverted. This contract currently deposits directly into LST contract 1:1. It should be noted that a more favorable trade could be possible via DEXs.*

### [State Variables](broken://pages/jjlGw7th4hq2Dh0KVwV0) <a href="#state-variables" id="state-variables"></a>

#### [flashloanInitiated](broken://pages/jjlGw7th4hq2Dh0KVwV0) <a href="#flashloaninitiated" id="flashloaninitiated"></a>

```
uint256 private flashloanInitiated = 1;
```

### [Functions](broken://pages/jjlGw7th4hq2Dh0KVwV0) <a href="#functions" id="functions"></a>

#### [flashLeverageCollateral](broken://pages/jjlGw7th4hq2Dh0KVwV0) <a href="#flashleveragecollateral" id="flashleveragecollateral"></a>

Transfer collateral from user + flashloan collateral from balancer -> deposit all collateral into `IonPool` -> borrow WETH from `IonPool` -> mint collateral using WETH -> repay Balancer flashloan.

*Code assumes Balancer flashloans remain free.*

```
function flashLeverageCollateral(
    uint256 initialDeposit,
    uint256 resultingAdditionalCollateral,
    uint256 maxResultingDebt,
    bytes32[] calldata proof
)
    external
    onlyWhitelistedBorrowers(proof);
```

**Parameters**

| Name                            | Type        | Description                                                                                                                                                                                                                                                             |
| ------------------------------- | ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `initialDeposit`                | `uint256`   | in collateral terms. \[WAD]                                                                                                                                                                                                                                             |
| `resultingAdditionalCollateral` | `uint256`   | in collateral terms. \[WAD]                                                                                                                                                                                                                                             |
| `maxResultingDebt`              | `uint256`   | in WETH terms. While it is unlikely that the exchange rate changes from when a transaction is submitted versus when it is executed, it is still possible so we want to allow for a bound here, even though it doesn't pose the same level of threat as slippage. \[WAD] |
| `proof`                         | `bytes32[]` | used to validate the user is whitelisted.                                                                                                                                                                                                                               |

#### [\_flashLeverageCollateral](broken://pages/jjlGw7th4hq2Dh0KVwV0) <a href="#flashleveragecollateral" id="flashleveragecollateral"></a>

*Assumes that the caller has already transferred the deposit asset. Can be called internally by a wrapper that needs additional logic to obtain the LST. Ex) Zapping stEth to wstETH.*

```
function _flashLeverageCollateral(
    uint256 initialDeposit,
    uint256 resultingAdditionalCollateral,
    uint256 maxResultingDebt
)
    internal;
```

#### [flashLeverageWeth](broken://pages/jjlGw7th4hq2Dh0KVwV0) <a href="#flashleverageweth" id="flashleverageweth"></a>

Transfer collateral from user + flashloan WETH from balancer -> mint collateral using WETH -> deposit all collateral into `IonPool` -> borrow WETH from `IonPool` -> repay Balancer flashloan.

*Code assumes Balancer flashloans remain free.*

```
function flashLeverageWeth(
    uint256 initialDeposit,
    uint256 resultingAdditionalCollateral,
    uint256 maxResultingDebt,
    bytes32[] calldata proof
)
    external
    payable
    onlyWhitelistedBorrowers(proof);
```

**Parameters**

| Name                            | Type        | Description                                                                                                                                                                                                                                                             |
| ------------------------------- | ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `initialDeposit`                | `uint256`   | in collateral terms. \[WAD]                                                                                                                                                                                                                                             |
| `resultingAdditionalCollateral` | `uint256`   | in collateral terms. \[WAD]                                                                                                                                                                                                                                             |
| `maxResultingDebt`              | `uint256`   | in WETH terms. While it is unlikely that the exchange rate changes from when a transaction is submitted versus when it is executed, it is still possible so we want to allow for a bound here, even though it doesn't pose the same level of threat as slippage. \[WAD] |
| `proof`                         | `bytes32[]` | used to validate the user is whitelisted.                                                                                                                                                                                                                               |

#### [\_flashLeverageWeth](broken://pages/jjlGw7th4hq2Dh0KVwV0) <a href="#flashleverageweth" id="flashleverageweth"></a>

*Assumes that the caller has already transferred the deposit asset. Can be called internally by a wrapper that needs additional logic to obtain the LST. Ex) Zapping stEth to wstETH.*

```
function _flashLeverageWeth(
    uint256 initialDeposit,
    uint256 resultingAdditionalCollateral,
    uint256 maxResultingDebt
)
    internal;
```

#### [receiveFlashLoan](broken://pages/jjlGw7th4hq2Dh0KVwV0) <a href="#receiveflashloan" id="receiveflashloan"></a>

This function is never intended to be called directly.

*Code assumes Balancer flashloans remain free. This function is intended to never be called directly. It should only be called by the Balancer VAULT during a flashloan initiated by this contract. This callback logic only handles the creation of leverage positions by minting. Since atomic withdrawals are not possible, deleveraging with a flashloan directly through an LST provider is not possible.*

```
function receiveFlashLoan(
    IERC20Balancer[] memory tokens,
    uint256[] memory amounts,
    uint256[] memory,
    bytes memory userData
)
    external
    override;
```

**Parameters**

| Name       | Type               | Description                                         |
| ---------- | ------------------ | --------------------------------------------------- |
| `tokens`   | `IERC20Balancer[]` | Array of tokens flashloaned.                        |
| `amounts`  | `uint256[]`        | Amounts flashloaned.                                |
| `<none>`   | `uint256[]`        |                                                     |
| `userData` | `bytes`            | Arbitrary data passed from initiator of flash loan. |

#### [\_depositWethForLst](broken://pages/jjlGw7th4hq2Dh0KVwV0) <a href="#depositwethforlst" id="depositwethforlst"></a>

Unwraps weth into eth and deposits into lst contract.

*Unwraps weth into eth and deposits into lst contract.*

```
function _depositWethForLst(uint256 amountWeth) internal virtual returns (uint256);
```

**Parameters**

| Name         | Type      | Description                        |
| ------------ | --------- | ---------------------------------- |
| `amountWeth` | `uint256` | The WETH amount to deposit. \[WAD] |

**Returns**

| Name     | Type      | Description                    |
| -------- | --------- | ------------------------------ |
| `<none>` | `uint256` | Amount of lst received. \[WAD] |

#### [\_getEthAmountInForLstAmountOut](broken://pages/jjlGw7th4hq2Dh0KVwV0) <a href="#getethamountinforlstamountout" id="getethamountinforlstamountout"></a>

Calculates the amount of eth required to receive `amountLst`.

*Calculates the amount of eth required to receive `amountLst`.*

```
function _getEthAmountInForLstAmountOut(uint256 amountLst) internal view virtual returns (uint256);
```

**Parameters**

| Name        | Type      | Description                   |
| ----------- | --------- | ----------------------------- |
| `amountLst` | `uint256` | Desired output amount. \[WAD] |

**Returns**

| Name     | Type      | Description                                 |
| -------- | --------- | ------------------------------------------- |
| `<none>` | `uint256` | Eth required for desired lst output. \[WAD] |

### [Errors](broken://pages/jjlGw7th4hq2Dh0KVwV0) <a href="#errors" id="errors"></a>

#### [ReceiveCallerNotVault](broken://pages/jjlGw7th4hq2Dh0KVwV0) <a href="#receivecallernotvault" id="receivecallernotvault"></a>

```
error ReceiveCallerNotVault(address unauthorizedCaller);
```

#### [FlashLoanedTooManyTokens](broken://pages/jjlGw7th4hq2Dh0KVwV0) <a href="#flashloanedtoomanytokens" id="flashloanedtoomanytokens"></a>

```
error FlashLoanedTooManyTokens(uint256 amountTokens);
```

#### [FlashloanedInvalidToken](broken://pages/jjlGw7th4hq2Dh0KVwV0) <a href="#flashloanedinvalidtoken" id="flashloanedinvalidtoken"></a>

```
error FlashloanedInvalidToken(address tokenAddress);
```

#### [ExternalBalancerFlashloanNotAllowed](broken://pages/jjlGw7th4hq2Dh0KVwV0) <a href="#externalbalancerflashloannotallowed" id="externalbalancerflashloannotallowed"></a>

```
error ExternalBalancerFlashloanNotAllowed();
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.ionprotocol.io/devs/smart-contract-architecture/flash/balancerflashloandirectminthandler.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
