Integrate Fluid token swaps

Liquidations in Fluid are simpler and more gas-efficient than a UniswapV3 swap. If liquidations are available, the swapper gets a significant discount to the available market rate. Integrating and making use of those available swaps is hence very beneficial.

VaultLiquidationResolver

All available swaps, swap paths and helper methods are available via a dedicated resolver contract, see autogenerated docs for the contract.

Deployment addresses
NetworkAddressLink
Mainnet0x6Cd1E75b524D3CCa4c3320436d6F09e24Dadd613Etherscan
Arbitrum0x27F0Cb52138e97A66295Eeed523c9698E1125Fa9Arbiscan
Base0x0e85C7d3764343A2924D9cDC6Fea1695De3243cCBasescan

General

  • swap methods are expected to be called via callStatic, although they would not be doing any state changes anyway.
  • for native token, send 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE.

Get all currently available swaps

The method getAllVaultsSwap returns all currently available swaps, filtered by the best available rate swap for each Fluid vault. This can be useful to find profitable trades, arbitrage opportunities, running a liquidation bot etc.

Get best available swap for a certain swap and input amount

The exactInput method returns the currently best available swaps, sorted by best ratio and filtered to a given input amount. The returned swaps are optimized for the vast majority of possible cases whilst allowing for a very simple integration. This will be enough for most use-cases. Some custom optimization might be possible, see Advanced methods below.

Creating execution payloads

The getSwapTx or for multiple swaps at once the getSwapTxs methods build the calldata for executing the swaps. The returned calldata executes liquidate() on the given Fluid vault protocol, with the defined input token amount and maximum allowed slippage.

Note that for swaps where the input token is the native token, it is necessary to send the inAmt along as msg.value.

Build manually

Alternatively you can also manually build the payload, the interface for the liquidate() method is (also see contract docs):

/// @notice allows to liquidate all bad debt of all users at once. Liquidator can also liquidate partially any amount they want.
/// @param debtAmt_ total debt to liquidate (aka debt token to swap into collateral token)
/// @param colPerUnitDebt_ minimum collateral token per unit of debt in 1e18 decimals (aka slippage)
/// @param to_ address at which collateral token should go to.
/// @param absorb_ if true then liquidate from absorbed first
/// @return actualDebtAmt_ if liquidator sends debtAmt_ more than debt remaining to liquidate then actualDebtAmt_ changes from debtAmt_ else remains same
/// @return actualColAmt_ total liquidated collateral which liquidator will get
function liquidate(
    uint256 debtAmt_,
    uint256 colPerUnitDebt_,
    address to_,
    bool absorb_
) public payable returns (uint actualDebtAmt_, uint actualColAmt_);

Advanced methods

Get swaps for previously fetched paths

The return data of the get path view methods can be fed into getSwapsForPaths the fetch the available swaps for those.

Get swaps for a certain output amount

It is not possible to guarantee a certain output amount as a Fluid liquidation uses a fixed input amount as input param. The output amount will vary and change between one block and the next also because of oracle pricing etc. This it is only possible to estimate approximate swaps for a given target output amount with the method approxOutput. The maximum allowed difference should by tightly controlled via the maximum defined slippage.

Get all possbile swap paths

Use the method getAllSwapPaths to get all possible swap paths. Alternatively you can use the methods getSwapPaths or getAnySwapPaths to get possible swap paths for certain input token to certain output token combination(s).

Getting raw swap data

The methods named ending with SwapData return the raw swap data as currently available on certain Fluid vaults. This is basically the data that the VaultResolver returns for the method getVaultLiquidation().

Custom optimization via swap methods

The default swap methods come with built-in optimization to only return the best rate swap for each Fluid vault. The exactInput and approxOutput methods come with slightly better built-in optimization which is possible because of the defined input amount. There are however edge cases which could be even better optimized for, e.g. the rate for the withAbsorb only liquidity could be better than the without absorb liquidity. See the code for more info.

For advanced use-cases, all swap methods also have a Raw version method, which returns the exact same data just unoptimized. Meaning for the same vault, both the withAbsorb and the withoutAbsorb swaps will be returned, if both are available. Note that triggering a liquidation with absorb set to true will also tap into the liquidity of without absorb once the with absorb liquidity is used up.

Filter swaps

The filterToTargetInAmt and filterToApproxOutAmt are helper methods which sort and filter the input swaps to a certain target amount. This can be useful when doing custom optimization. These methods should be used in combination with the returned swaps of Raw ending methods. Note this only works for swaps of the same path (input token -> output token). For mixed path swaps the result will be wrong.