BalancerFlashloanDirectMintHandler

Git Source

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

flashloanInitiated

uint256 private flashloanInitiated = 1;

Functions

flashLeverageCollateral

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

_flashLeverageCollateral

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

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

_flashLeverageWeth

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

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

_depositWethForLst

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

Returns

_getEthAmountInForLstAmountOut

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

Returns

Errors

ReceiveCallerNotVault

error ReceiveCallerNotVault(address unauthorizedCaller);

FlashLoanedTooManyTokens

error FlashLoanedTooManyTokens(uint256 amountTokens);

FlashloanedInvalidToken

error FlashloanedInvalidToken(address tokenAddress);

ExternalBalancerFlashloanNotAllowed

error ExternalBalancerFlashloanNotAllowed();