Liquidate a vault
Learn how to liquidating a vault programmatically on the Cozy protocol.
Users who borrow funds are required to maintain a minimal level of account liquidity. If their account falls below the minimum liquidity threshold, they risk liquidation and losing their collateral.
Users can avoid liquidation by adding collateral or repaying debts. If a user with an account at risk of liquidation fails to respond—by adding collateral or repaying outstanding debt—the account will eventually have negative account liquidity, also known as a shortfall. Any user account with negative account liquidity can be liquidated and taken over programmatically by someone else. By liquidating an account with a shortfall, you can seize its assets at a discount.
This guide illustrates how you can liquidate vaults programmatically using a script written in TypeScript.
All code snippets in this guide are from the liquidate.ts
script in the Cozy developer guides repository. See that repository for more context, definitions of helper methods used, and related information.
Check account liquidity
The collateral value of an account is computed by multiplying the supplied USD balance in a market by that market's collateral factor, and summing the result across all markets. The total USD borrow balances for a user are subtracted from that result to arrive at the account liquidity value.
Only accounts with negative liquidity, also known as a shortfall, can be liquidated. Therefore, before liquidating an account, you need to check whether the account has a shortfall. The following code snippet illustrates how to check if an account has a shortfall using an arbitrary address.
% hint style="info" %} The sample script uses an arbitrary address because there's no way to guarantee there is a mainnet account with negative liquidity that could actually be liquidated. The comments describe what to expect if the arbitrary account could be liquidated.
Liquidate an account
If the script had found that the arbitrary account had a shortfall, it would proceed with liquidating the account. In liquidating the account, you can configure the script to repay some or all of the outstanding debt on behalf of the borrower. As a result of the liquidation, you receive some of the borrower's collateral at a discount. Receiving a portion of a borrower's collateral at a discount is referred to as the liquidation incentive.
As an account liquidator, you first need to determine the maximum percentage of the outstanding debt for an account that can be closed by repayment.
The following code snippet illustrates how to check the maximum percentage—called the close factor—that can be closed by liquidation:
As part of the liquidation process, you can choose one of the assets that were supplied as collateral by the borrower as the asset you'll seize and receive at a discount. If needed, you could get a list of available collateral using the getAssetsIn()
method described in Viewing Positions guide. For simplicity, the following code snippet assumes the collateral is ETH and the borrow is a protected Yearn yUSDC vault, then checks how much this user has borrowed and computes the maximum repay amount.
After the collateral is seized, the seized amount is transferred as Cozy tokens. Those tokens can be redeemed as if you had supplied the collateral asset yourself. Remember to approve the Cozy token contract to spend your tokens before calling liquidateBorrow()
.
The following code snippet illustrates executing the liquidation. However, in this case, the account to liquidate does not have a shortfall. Therefore, the findLog()
method reports that the LiquidateBorrow
event was not found and prints an error code (3) this corresponds to the COMPTROLLER_REJECTION
failure message. Looking at the Comptroller's liquidateBorrowAllowed
hook, you can find that the Comptroller rejected the liquidation because there is no shortfall.
Last updated