Liquidation Bot
Parallel Liquidation Bot Technical Designs
Last updated
Parallel Liquidation Bot Technical Designs
Last updated
Liquidation happens when a borrower’s health factor goes below 1 and their collateral cannot adequately cover their loan to debt value. Liquidations are necessary to reduce risks to the protocol.
This is a micro-service-based architecture. The orange parts are the producers and the green part is the consumer. As a message bus, Redis connects all the services. Each micro-service can run as a process or a thread. Each service can have its scanning interval to configure different latencies.
We call the accounts whose HF is below 1 as shortfall (underwater) accounts, and these accounts are also the target to be liquidated by the liquidation bot.
The scanner will do these things:
Before liquidating, we need to know all the borrowers' accounts that can be liquidated. We scan the Borrow Event by using FilterLogs JSON-RPC to get all the accounts that have completed borrow operations. These are the potential accounts for liquidation.
Afterward, we store the borrowers into Redis SET.
["BorrowerAddress1", "BorrowerAddress2"]
This scanner will scan all the borrowers and checks the status for each. If the account health factor is below 1, they are marked as a shortfall account and then put into shortfall SET.
["ShortfallAddress1", "ShortfallAddress2"]
This scanner is only designed for NFT liquidation, its goal is to get the offers from multiple platforms and then store them in Redis in real-time, which can be read in time for the liquidator to liquidate the corresponding NFT. So, when this scanner is running, it will get the offers from each platform, through the offer data structure is different for each platform, we will stringify the data and store it in Redis.
"OpenseaOffer_MAYC" => "actual_data_info"
The liquidator will get the shortfall accounts from Redis, and for each account, it will try to generate its liquidation task, which is divided into two categories, one is ERC20 and the other is ERC721 (NFT). We have HealthFactor(HF) and ERC721HealthFactor(ERC721HF) to determine whether a certain category of a token can be liquidated or not. For HF < 1
, we can try to liquidate ERC20, but if we want to liquidate NFT, the protocol also require ERC721HF < 1
as well.
For ERC20 liquidation:
Check the account position for both supplies and borrow using getUserReserveData ABI. Choose a liquidation parameter by using a simple strategy.
And then call the liquidateERC20
method in liquidator contract, thus we can liquidate ERC20 by flashloan.
For NFT liquidation:
If we find an NFT that can be liquidated, we need to find a valid offer from Redis to match it. Because when the bot constructs the liquidation parameters, the bot needs to give an offer parameter so that the NFTFlashloanLiquidator
can complete the offer and get the corresponding offered token to repay the assets of flashloan. So the liquidation bot needs to make sure that this offer can be successfully executed.
And then call the liquidateERC721
method in the liquidator contract, thus we can liquidate ERC721 by flashloan.
After the service gets the shortfall accounts from Redis SET, the liquidator will liquidate these shortfall accounts immediately. It will check which asset type (if it includes only ERC20 or both ERC20 and ERC721) can be liquidated by HealthFactor and Erc721HealthFactor. Call the corresponding external liquidation function on the ERC20 liquidation contract or the ERC721 liquidation contract.
For NFT, there are two types of offers: collection offer
and token offer
. collection offer means that it will receive any token of the collection, the id is not a constraint, whereas the token offer is the exact opposite, it constrains the offer must receive the collection with the specified token id, otherwise, it cannot be completed.
For both types of offers, we choose the offer with the highest price to liquidate according to a greedy strategy. However, the actual profit of our final liquidation transaction cannot be judged by the price alone, because each platform's offer has a different fee strategy, and the liquidator contract also has operational fees which need to be considered.
Specifically, when we consider choosing an offer, we need to consider the fee for
The offer its own contained fee.
The flash loan fee for the liquidator contract to operate.
The swap fee for the Uniswap token exchange, also for the liquidator contract to operate.
The liquidation protocol fee that configurated in Parallel.
At last, we choose the offer with the highest price - fees
value for the liquidation.
Once the bot finds a profitable offer to liquidate, we will use the flashloan contract to liquidate the NFT, and the profit from the liquidation will eventually be transferred to the owner's address of the flashloan contract. For instance, to liquidate an NFT with USDC, the specific liquidation process can be described as follows.
NOTE: The caller is an executor of the liquidator contract, this address doesn’t hold any asset, so we need to flashloan the corresponding asset to do liquidating.
use Flashloan to borrow the required USDC assets
use the hold USDC assets to call Pool.liquidationERC721 for liquidation
sell the liquidated NFT by completing the offer, and getting the assets provided by the offer
swap the offer traded assets (e.g. WETH) to USDC via UNISWAP
use USDC to repay the flashloan in step 1
complete liquidation
How to calculate the profit?
liquidation earnings
LiquidationBonus: configurated by parallel protocol, take 5%
as an example
It also means liquidation incentives, specifically, the liquidator is able to take the collateralized NFT at a discount price.
Fund provided by the offer: This May be higher or lower than the NFT value(floor price). In this case, we assume that the fund is 105 % * NFT_Value, and we can get a 5%
reward.
liquidation costs
Flashloan fee: about 0.09 %
per-time
if we flashloan USDC to repay the loan, we need to charge the flashloan fee
Swap fee: about 0.3 % per-time, the average will consume 3 * 0.3% = 0.9%
if the liquidation asset(such as USDC) supports flashloan, we only need to swap once.
but if the liquidation asset(such as USDT and APE) does not support flashloan, we need to swap more times.
LiquidationProtocolFee: configurated by Parallel protocol, take 10%
as an example
if LiquidationBonus is 5% and LiquidationProtocolFee is 10%, we end up paying 5% * 10% = 0.5%
protocol fee.
Offer fee: determined by the order itself, the offer may be from many different marketplaces, and different marketplaces have different strategies. In this case, we assume that the fee is 5%
.
Thus, in this case
Eventually, these profits will be transferred to the owner’s address of the ERC721LiquidatorContract.
FlashloanLiquidator
contract will borrow a FlashLoan to get the liquidation fund and repay the loan to acquire the incentive rewards.
A simple process to liquidate ERC20 with flashloan:
These are the following components:
Flashloan Pool - Currently we are using AAVE V2 as the FlashLoan Pool.
Parallel Pool - The pool contract of Parallel protocol.
UniswapV2 - Swap flashloan asset to debt asset or collateral asset to flashLoan asset.
function liquidateERC20(LiquidateERC20Params memory params) external;
Call Params
Name | Type | Description |
---|---|---|
params |
| this struct contains some liquidation related parameters.
|
Since the NFT can’t be easily sold, it may not be possible to use FlashLoan's liquidation funds. Let's take the following strategy:
If the NFT to be liquidated has a bid order in other NFT markets, such as Parallel, Opensea, Looksrare, etc, the NFTFlashloanLiquidator
contract will borrow the asset from FlashLoan to liquidate the NFT, and then match the bid order. After obtaining the funds, repay the Flash loan.
If the NFT to be liquidated does not have a suitable bid order, liquidate the NFT with the liquidation bot's own funds and make a sell order to Parallel protocol or Opensea, etc.
A simple process to liquidate NFT with flashloan and NFT bid:
Compared with ERC20 flashloan liquidation, it has the following additional components:
NFT Market Adaptor - A library of liquidator contract that integrates methods for interacting with various NFT markets.
For UNI-V3-POS, NFTFlashloanLiquidator
contract will remove all liquidity of its position and collect fee after the NFT has been liquidated, And then swap the token0
and token1
to WETH
if necessary.
In the end, If there are any remaining offer tokens or flash loan assets, they will be transferred to the bot owner as profits.
Currently, we can get NFT bid orders which contain token bids and collection bids from the following markets.
Market | Token Bid | Collection Bid |
---|---|---|
Opensea | supported | not supported |
Looksrare | supported | supported |
Parallel | supported | supported |
CryptoPunksMarket | supported | not supported |
NFTX | supported | supported |
Sudo | supported | supported |
For CryptoPunks, all its bid orders are stored in its own contract, So we can directly interact with the contract to get bid orders and sell the NFT.
function liquidateERC721( bytes calldata _fullParamsBytes, bytes calldata _liquidateParamsBytes) external;
Call Params
Name | Type | Description |
---|---|---|
_fullParamsBytes |
| encoded complete parameters that contains the market type and bid order and liquidation parameters and flashloan parameters |
_liquidateParamsBytes |
| encoded liquidation parameters |