Many leading lending protocols have poorly optimized risk parameters that are based solely on the collateral being liquidated. This has resulted in massive capital inefficiency since many loans are overcollateralized far in excess of the actual risks at play. Instead of setting risk parameters on the basis of collateral, the protocol sets risk parameters on the basis of trading pairs.
The table below lists the margin maintenance requirements for each trading pair on Ooki. If the margin falls below the levels listed below the position will be liquidated.
ETH - wBTC
ETH - LINK, YFI, AAVE
ETH - Stablecoin
ETH - MRK, KNC
ETH - BZRX
Stablecoin - Stablecoin
ERC20 - ERC20
wBTC - Stablecoin
YFI/LINK/AAVE - Stablecoin
MKR, KNC -Stablecoin
BZRX - Stablecoin
Positions that become undercollateralized are only liquidated enough to bring margin maintenance above the threshold for a given pair.
Loans are liquidated if the position goes below margin maintenance. But only partially, enough to bring margin up 10% above margin maintenance. Only liquidating as much as necessary reduces the risk of slippage from large liquidations.
Anyone can initiate a margin call: the process is permissionless and incentivized. The incentive to liquidators is a refund of your gas * 2. There’s also no capital costs or risks like those experienced when liquidating positions on other protocols. This ensures redundancy in the margin calling process. Moreover, there is an insurance fund which protects lenders. In the case that a lender would lose their principal, the insurance fund will automatically disburse funds to the lender. This insurance is funded by a smart contract holding 10% of all interest that is paid by borrowers to lenders.
The liquidation engine is a two-tiered system designed to maximally capitalize on the efficiency of DEX liquidations, keeping dollars in the hands of users rather than miners and capital intensive liquidation bots.
Tier 1: The first line of defense. Tier 1 allows users to delegate calling the close() function on their position to a contract that anyone can call permissionlessly. If the position is not at margin maintenance, the transaction reverts. Anyone can call the close() function near margin maintenance to receive a bounty. This bounty is in the form of both a flat and percentage-based fee that is taken out of collateral. The flat fee is intended to cover gas, while the percentage-based fee is intended to preferentially attract liquidators to larger positions. The payout is ultimately determined by the borrowers and traders opening positions. While it is possible to opt out or change the bounty to zero, doing so puts users at risk of incurring much larger liquidation costs if their position is forced to undergo a collateral auction.
Tier 2 (Collateral Auction): If a position is below margin maintenance and Tier 1 (described above) has failed to close the position, anyone who calls liquidate() will be entitled to purchase the collateral from the insolvent account at a discount. The collateral is valued using Chainlink price feeds. Each collateral has its own discount factor depending on the risk parameters of the asset. Both the volatility and depth of liquidity will be considered when determining the discount factor for any given collateral. Liquidators face two main risks when liquidating collateral: that the price changes while they hold it (volatility risk), and that the slippage turns the liquidation unprofitable (liquidity risk). Generally, the discount applied during the collateral auction will reflect the overall depth of liquidity available to that asset across all exchanges. Since liquidation penalties from collateral auctions can be significant, it is in the best interest of borrowers and traders to either close the position in a timely manner or enable Fulcrum Saver.
The following code can be used to call all active loans
/// @dev get current active loans in the system
/// @param start of the index
/// @param count number of loans to return
/// @param unsafeOnly boolean if true return unsafe loan only (open for liquidation)
/// @param isLiquidatable boolean if true return liquidatable loans only
) external view returns (LoanReturnData memory loansData);
Then you can use the function below to liquidate the loan:
/// @dev liquidates unhealty loans
/// @param loanId id of the loan
/// @param receiver address receiving liquidated loan collateral
/// @param closeAmount amount to close denominated in loanToken
/// @return loanCloseAmount amount of the collateral token of the loan
/// @return seizedAmount sezied amount in the collateral token
/// @return seizedToken loan token address
The liquidator is given the following reward for liquidating the loan:
- Any remaining collateral margin maintenance - 100% as a reward for liquidating the loan.