UniswapFlashloanBalancerSwapHandler

Git Source

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

VAULT

IVault internal constant VAULT = IVault(0xBA12222222228d8Ba445958a75a0704d566BF2C8);

WETH_IS_TOKEN0_ON_UNISWAP

bool immutable WETH_IS_TOKEN0_ON_UNISWAP;

FLASHLOAN_POOL

IUniswapV3Pool public immutable FLASHLOAN_POOL;

BALANCER_POOL_ID

bytes32 public immutable BALANCER_POOL_ID;

Functions

constructor

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

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

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

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

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

WethNotInPoolPair

error WethNotInPoolPair(IUniswapV3Pool pool);

ReceiveCallerNotPool

error ReceiveCallerNotPool(address unauthorizedCaller);

Structs

FlashCallbackData

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