FluidVaultLiquidationResolver ​
Resolver contract that helps in finding available token (liquidation) swaps available in Fluid VaultT1s.
Note that on the same protocol, if "withAbsorb = true" is executed, this also consumes the swap that would be on the same protocol with "withAbsorb = false". So the total available swap amount at a protocol if both a swap with and without absorb is available is not with inAmt + without inAmt
but rather with inAmt
. Sometimes with absorb can provide better swaps, sometimes without absorb can provide better swaps. But available liquidity for "withAbsorb" amounts will always be >= without absorb amounts.
The "Raw" methods return both the with and without absorb swaps for the same Fluid Vault, the non-"Raw" methods automatically filter by the better ratio swap. For same cases a better optimization of ratios is possible with custom logic based on the "Raw" methods, see details in comments.
for native token, send 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE.
returned swaps Struct can be fed into getSwapTx
to prepare the tx that executes the swaps.
non-view methods in this contract are expected to be called with callStatic, although they would anyway not do any actual state changes.
Functions ​
constructor ​
constructor sets the immutable vault resolver address
constructor(IFluidVaultResolver vaultResolver_) Variables(vaultResolver_);
getAllSwapPaths ​
returns all available token swap paths
function getAllSwapPaths() public view returns (SwapPath[] memory paths_);
getSwapPaths ​
returns all swap paths for a certain tokenIn_
swapped to a tokenOut_
. returns empty array if no swap path is available for a given pair.
function getSwapPaths(address tokenIn_, address tokenOut_) public view returns (SwapPath[] memory paths_);
getAnySwapPaths ​
returns all available swap paths for any tokensIn_
to any tokensOut_
.
function getAnySwapPaths(address[] calldata tokensIn_, address[] calldata tokensOut_)
public
view
returns (SwapPath[] memory paths_);
getVaultSwapData ​
returns the swap data for with and without absorb for a Fluid vault_
.
function getVaultSwapData(address vault_)
public
returns (SwapData memory withoutAbsorb_, SwapData memory withAbsorb_);
getVaultsSwapData ​
returns the swap data for with and without absorb for multiple Fluid vaults_
.
function getVaultsSwapData(address[] memory vaults_)
public
returns (SwapData[] memory withoutAbsorb_, SwapData[] memory withAbsorb_);
getAllVaultsSwapData ​
returns the swap data for with and without absorb for all Fluid vaults.
function getAllVaultsSwapData() public returns (SwapData[] memory withoutAbsorb_, SwapData[] memory withAbsorb_);
getSwapForProtocol ​
returns the available swap amounts at a certain protocol_
. Only returns non-zero swaps. For vault protocol considering both a swap that uses liquidation with absorb and without absorb.
function getSwapForProtocol(address protocol_) public returns (Swap memory swap_);
getVaultsSwapRaw ​
returns all available swaps_
for multiple Fluid vaults_
raw. Only returns non-zero swaps. includes all swaps unfiltered, e.g. with absorb and without absorb swaps are present for the same vault.
function getVaultsSwapRaw(address[] memory vaults_) public returns (Swap[] memory swaps_);
getAllVaultsSwapRaw ​
returns all available swaps_
for all Fluid vaults raw. Only returns non-zero swaps. includes all swaps unfiltered, e.g. with absorb and without absorb swaps are present for the same vault.
function getAllVaultsSwapRaw() public returns (Swap[] memory swaps_);
getSwapsForPathsRaw ​
returns all the available swaps_
for certain swap paths_
. Only returns non-zero swaps. includes all swaps unfiltered, e.g. with absorb and without absorb swaps are present for the same vault.
function getSwapsForPathsRaw(SwapPath[] memory paths_) public returns (Swap[] memory swaps_);
getSwapsRaw ​
finds all available swaps_
for tokenIn_
to tokenOut_
. includes all swaps unfiltered, e.g. with absorb and without absorb swaps are present for the same vault.
function getSwapsRaw(address tokenIn_, address tokenOut_) public returns (Swap[] memory swaps_);
getAnySwapsRaw ​
finds all available swaps_
for any tokensIn_
to any tokesnOut_
. Token pairs that are not available or where available swap amounts are zero will not be present in the returned swaps_
array. includes all swaps unfiltered, e.g. with absorb and without absorb swaps are present for the same vault.
function getAnySwapsRaw(address[] calldata tokensIn_, address[] calldata tokensOut_)
public
returns (Swap[] memory swaps_);
getVaultsSwap ​
returns all available swaps_
for multiple Fluid vaults_
. Only returns non-zero swaps. returns only either the with absorb swap or without absorb swap for each vault, whichever has the better ratio.
function getVaultsSwap(address[] memory vaults_) public returns (Swap[] memory swaps_);
getAllVaultsSwap ​
returns all available swaps_
for all Fluid vaults. Only returns non-zero swaps. returns only either the with absorb swap or without absorb swap for each vault, whichever has the better ratio.
function getAllVaultsSwap() public returns (Swap[] memory swaps_);
getSwapsForPaths ​
returns all the available swaps_
for certain swap paths_
. Only returns non-zero swaps. returns only either the with absorb swap or without absorb swap for each vault, whichever has the better ratio.
function getSwapsForPaths(SwapPath[] memory paths_) public returns (Swap[] memory swaps_);
getSwaps ​
finds all available swaps_
for tokenIn_
to tokenOut_
. returns only either the with absorb swap or without absorb swap for each vault, whichever has the better ratio.
function getSwaps(address tokenIn_, address tokenOut_) public returns (Swap[] memory swaps_);
getAnySwaps ​
finds all available swaps_
for any tokensIn_
to any tokesnOut_
. Token pairs that are not available or where available swap amounts are zero will not be present in the returned swaps_
array. returns only either the with absorb swap or without absorb swap for each vault, whichever has the better ratio.
function getAnySwaps(address[] calldata tokensIn_, address[] calldata tokensOut_)
public
returns (Swap[] memory swaps_);
getSwapTx ​
returns the calldata to execute a swap as returned by the other methods in this contract. swap_.data.inAmt
must come from msg.sender, swap_.data.outAmt
goes to receiver_
. If the input token is the native token, msg.value must be sent along when triggering the actual call with the returned calldata which should be swap_.data.inAmt
.
function getSwapTx(Swap calldata swap_, address receiver_, uint256 slippage_)
public
pure
returns (address target_, bytes memory calldata_);
Parameters
Name | Type | Description |
---|---|---|
swap_ | Swap | Swap struct as returned by other methods |
receiver_ | address | receiver address that the output token is sent to |
slippage_ | uint256 | maximum allowed slippage for the expected output token amount. Reverts iIf received token out amount is lower than this. in 1e4 percentage, e.g. 1% = 10000, 0.3% = 3000, 0.01% = 100, 0.0001% = 1. |
Returns
Name | Type | Description |
---|---|---|
target_ | address | target address where calldata_ must be executed |
calldata_ | bytes | the calldata that can be used to trigger the liquidation call, resulting in the desired swap. |
getSwapTxs ​
returns the same data as getSwapTx
for an array of input swaps_
at once.
function getSwapTxs(Swap[] calldata swaps_, address receiver_, uint256 slippage_)
public
pure
returns (address[] memory targets_, bytes[] memory calldatas_);
exactInput ​
finds all swaps from tokenIn_
to tokenOut_
for an exact input amount inAmt_
. filters the available swaps and sorts them by ratio, so the returned swaps are the best available swaps to reach the target inAmt_
. If the full available amount is less than the target inAmt_
, the available amount is returned as actualInAmt_
.
The only cases that are currently not best possible optimized for are when the ratio for withoutAbsorb is better but the target swap amount is more than the available without absorb liquidity. For this, currently the available withAbsorb liquidity is consumed first before tapping into the better ratio withoutAbsorb liquidity. The optimized version would be to split the tx into two swaps, first executing liquidate() with absorb = false to fully swap all the withoutAbsorb liquidity, and then in the second tx run with absorb = true to fill the missing amount up to the target amount with the worse ratio with absorb liquidity.
function exactInput(address tokenIn_, address tokenOut_, uint256 inAmt_)
public
returns (Swap[] memory swaps_, uint256 actualInAmt_, uint256 outAmt_);
Parameters
Name | Type | Description |
---|---|---|
tokenIn_ | address | input token |
tokenOut_ | address | output token |
inAmt_ | uint256 | exact input token amount that should be swapped to output token |
Returns
Name | Type | Description |
---|---|---|
swaps_ | Swap[] | swaps to reach the target amount, sorted by ratio in descending order (higher ratio = better rate). Best ratio swap will be at pos 0, second best at pos 1 and so on. |
actualInAmt_ | uint256 | actual input token amount. Can be less than inAmt_ if all available swaps can not cover the target amount. |
outAmt_ | uint256 | output token amount received for actualInAmt_ |
approxOutput ​
finds all swaps from tokenIn_
to tokenOut_
for an APPROXIMATE output amount outAmt_
. filters the available swaps and sorts them by ratio, so the returned swaps are the best available swaps to reach the target outAmt_
. If the full available amount is less than the target outAmt_
, the available amount is returned as actualOutAmt_
. IMPORTANT: guaranteed exact output swaps are not possible with Fluid, this method only aims to approximately estimate the required input amounts to reach a certain output amount. This will change until execution and should be controlled with a maximum slippage. Recommended to use exact input methods instead.
The only cases that are currently not best possible optimized for are when the ratio for withoutAbsorb is better but the target swap amount is more than the available without absorb liquidity. For this currently the available withAbsorb liquidity is consumed first before tapping into the better ratio withoutAbsorb liquidity. The optimized version would be to split the tx into two swaps, first executing liquidate() with absorb = false to fully swap all the withoutAbsorb liquidity, and then in the second tx run with absorb = true to fill the missing amount up to the target amount with the worse ratio with absorb liquidity.
function approxOutput(address tokenIn_, address tokenOut_, uint256 outAmt_)
public
returns (Swap[] memory swaps_, uint256 inAmt_, uint256 approxOutAmt_);
Parameters
Name | Type | Description |
---|---|---|
tokenIn_ | address | input token |
tokenOut_ | address | output token |
outAmt_ | uint256 | exact output token amount that should be swapped to from input token |
Returns
Name | Type | Description |
---|---|---|
swaps_ | Swap[] | swaps to reach the target amount, sorted by ratio in descending order (higher ratio = better rate). Best ratio swap will be at pos 0, second best at pos 1 and so on. |
inAmt_ | uint256 | input token amount needed to receive actualOutAmt_ |
approxOutAmt_ | uint256 | approximate output token amount. Can be less than outAmt_ if all available swaps can not cover the target amount. |
filterToTargetInAmt ​
filters the swaps_
to the point where targetInAmt_
is reached. This is best used in combination with the "Raw" methods, as the targetInAmt_
allows for more optimized filtering than otherwise done with the non-"Raw" methods.
function filterToTargetInAmt(Swap[] memory swaps_, uint256 targetInAmt_)
public
returns (Swap[] memory filteredSwaps_, uint256 actualInAmt_, uint256 approxOutAmt_);
Returns
Name | Type | Description |
---|---|---|
filteredSwaps_ | Swap[] | swaps to reach the target amount, sorted by ratio in descending order (higher ratio = better rate). Best ratio swap will be at pos 0, second best at pos 1 and so on. |
actualInAmt_ | uint256 | actual input amount. Can be less than targetInAmt_ if all available swaps can not cover the target amount. |
approxOutAmt_ | uint256 | actual estimated output amount. |
filterToApproxOutAmt ​
filters the swaps_
to the point where APPROXIMATELY targetOutAmt_
is reached. IMPORTANT: guaranteed exact output swaps are not possible with Fluid, this method only aims to approximately estimate the required input amounts to reach a certain output amount. This will change until execution and should be controlled with a maximum slippage. Recommended to use exact input methods instead. This is best used in combination with the "Raw" methods, as the targetInAmt_
allows for more optimized filtering than otherwise done with the non-"Raw" methods.
function filterToApproxOutAmt(Swap[] memory swaps_, uint256 targetApproxOutAmt_)
public
returns (Swap[] memory filteredSwaps_, uint256 actualInAmt_, uint256 approxOutAmt_);
Returns
Name | Type | Description |
---|---|---|
filteredSwaps_ | Swap[] | swaps to reach the target amount, sorted by ratio in descending order (higher ratio = better rate). Best ratio swap will be at pos 0, second best at pos 1 and so on. |
actualInAmt_ | uint256 | actual input amount. |
approxOutAmt_ | uint256 | APPROXIMATE actual output amount. Can be less than targetOutAmt_ if all available swaps can not cover the target amount. |
_filterToTarget ​
filters the swaps_
to the point where either targetInAmt_
or targetOutAmt_
is reached. To filter only by in or only by out amount, send type(uint256).max
for the other param.
function _filterToTarget(Swap[] memory swaps_, uint256 targetInAmt_, uint256 targetOutAmt_)
internal
returns (Swap[] memory filteredSwaps_, uint256 actualInAmt_, uint256 actualOutAmt_);
Returns
Name | Type | Description |
---|---|---|
filteredSwaps_ | Swap[] | swaps to reach the target amount, sorted by ratio in descending order (higher ratio = better rate). Best ratio swap will be at pos 0, second best at pos 1 and so on. |
actualInAmt_ | uint256 | actual input amount. Can be less than targetInAmt_ if all available swaps can not cover the target amount. |
actualOutAmt_ | uint256 | actual output amount. Can be less than targetOutAmt_ if all available swaps can not cover the target amount. |
_sortByRatio ​
sorts swaps_
by ratio descending. Higher ratio is better (getting more output for input). Best ratio swap will be at pos 0, second best at pos 1 and so on
function _sortByRatio(Swap[] memory swaps_) internal pure returns (Swap[] memory);
_filterSwapsUntilTarget ​
filters swaps_
to exactly reach targetInAmt_
. Takes into consideration to filter out any swaps where both the withAbsorb and withoutAbsorb swap would be present for the same protocol, only leaving the withAbsorb swap (as that includes withoutAbsorb). Also returns the total in sumInAmt_
and out sumOutAmt_
amounts, which will be less than targetInAmt_
in the case that the target amount can not be reached even with all swaps.
function _filterSwapsUntilTarget(Swap[] memory swaps_, uint256 targetInAmt_, uint256 targetOutAmt_)
internal
returns (Swap[] memory filteredSwaps_, uint256 sumInAmt_, uint256 sumOutAmt_);
_getBetterRatioSwapData ​
gets the better swap based on ratio of with vs without absorb swap data.
function _getBetterRatioSwapData(SwapData memory withoutAbsorb_, SwapData memory withAbsorb_)
internal
pure
returns (SwapData memory swap_);
_getNonZeroSwaps ​
filters allSwaps_
to the non zero amount swaps_
, knowing the nonZeroSwapsCount_
function _getNonZeroSwaps(Swap[] memory allSwaps_, uint256 nonZeroSwapsCount_)
internal
pure
returns (Swap[] memory swaps_);
_getVaultTokens ​
gets the vault_
token in (borrow token) and token out (supply token)
function _getVaultTokens(address vault_) internal view returns (address tokenIn_, address tokenOut_);
_calcRatio ​
returns ratio for how much outAmt_ am I getting for inAmt_. scaled by 1e27
function _calcRatio(uint256 inAmt_, uint256 outAmt_) internal pure returns (uint256);
_getVaultT1s ​
returns all VaultT1 type protocols at the Fluid VaultFactory
function _getVaultT1s() internal view returns (address[] memory);
Errors ​
FluidVaultLiquidationsResolver__AddressZero ​
thrown if an input param address is zero
error FluidVaultLiquidationsResolver__AddressZero();
FluidVaultLiquidationsResolver__InvalidParams ​
thrown if an invalid param is given to a method
error FluidVaultLiquidationsResolver__InvalidParams();