Comment on page
Liquidation bot
Learn how to cover the debt of under-collateralised positions with the Omm smart contracts and a liquidation bot.
To maintain the health of the Omm protocol, you can liquidate borrowers who don't have enough collateral to cover their debt. You can do this by setting up a liquidation bot, or by interacting directly with the Omm smart contracts.
You can automate the liquidation process using the liquidation bot script on GitHub. You'll need to install Python on your device before you can run it.
The liquidation bot fetches a list of loans open on Omm, and checks the health factor (risk level) of each borrower. Borrowers with a health factor below
1
are added to the liquidation list, which are then sorted from highest -> lowest debt and liquidated.
- 1.
- 2.Open the
consts.py
file. - 3.Add the private key for your wallet to the
private_key
field. - 4.Add the contract address for the Omm address provider to the
score_address_provider
field (cx6a66130200b4f08c65ef394469404378ab52e5b6
for mainnet). - 5.Specify which network to run the bot on:
mainnet
for regular use, orlisbon
for testing. - 6.Save the file.
After you configure the bot, you can run
liquidation_bot.py
from Terminal or another command-line tool. Once it's finished, the transaction hash will be saved to a JSON file on your device.You can liquidate all borrowers, or only those you've specified:
- To liquidate all borrowers, run the script with
fetch_borrow_wallets()
. - To liquidate specific borrowers, use
fetch_user_borrow_wallet()
and specify each borrower's address:fetch_user_borrow_wallet(['hx...', 'hx...'])
.
To get a list of borrowers with bad debt, comment out the
def liquidate(self) and def save_txn_info(self)
sections before you run the script.
You can also liquidate borrowers by calling specific APIs on the Omm smart contracts. You can do this via contract interfaces provided through apps like Node Butler and the ICONex web wallet.
Query the
getBorrowWallets
method on the Lending Pool contract to fetch the list of borrowers. Borrowers are retrieved in batches of 50.
Query:
{
"contract": "LENDING_POOL",
"method": "getDepositWallets",
"params": {
"_index": 0
}
}
- Replace LENDING_POOL with the contract address (
cxcb455f26a2c01c686fa7f30e1e3661642dd53c0d
for mainnet).
Response:
["hxd47ad924eba01ec91330e4e996cf7b8c658f4e4c","hxfb6251ac765fd428c4f961ad649050bbbf77210d"...]
If a borrower's health factor is below
1
, they're under-collateralised and can be liquidated.To find wallets with a health factor below 1, query the
getUserAccountData
method on the Lending Pool Data Provider contract for each borrower. Open the JSON file it returns and look for healthFactorBelowThrehold
. If the value is true
or 0x1
, the borrower is under-collateralised.
Query:
{
"contract": "LENDING_POOL_DATA_PROVIDER",
"method": "getUserAccountData",
"params": {
"_user": 'hx...'
}
}
- Replace LENDING_POOL_DATA_PROVIDER with the contract address (
cx5f9a6ca11b2b761a469965cedab40ada9e503cb5
for mainnet).
Response:
{
"availableBorrowsUSD":"0x0",
"borrowingPower":"0x0",
"currentLiquidationThreshold":"0x905438e60010000",
"currentLtv":"0x6f05b59d3b20000",
"healthFactor":"0x7a7b6bc64e7ab80",
"healthFactorBelowThreshold":"0x1",
"totalBorrowBalanceUSD":"0x484b5520d32c480000",
"totalCollateralBalanceUSD":"0x67470be5bff61ec229",
"totalFeesUSD":"0x354a6ba7a18000",
"totalLiquidityBalanceUSD":"0x75f48ea4fc30c6e66f"
}
Query the
getUserLiquidationData
method for all under-collateralised borrowers on the Lending Pool Data Provider contract. It returns the amount of each asset a borrower has supplied and borrowed, and the amount that can be liquidated.
Query:
{
"contract": "LENDING_POOL_DATA_PROVIDER",
"method": "getUserLiquidationData",
"params": {
"_user": 'hx....'
}
}
- Replace LENDING_POOL_DATA_PROVIDER with the contract address (
cx5f9a6ca11b2b761a469965cedab40ada9e503cb5
for mainnet).
Response:
{
"badDebt":"0x10032432432453",
"borrows":{
"bnUSD":{
"compoundedBorrowBalance":"0xc2b7afcb396a8334e",
"compoundedBorrowBalanceUSD":"0xc2b7afcb396a8334e",
"maxAmountToLiquidate":"0x10032432432453",
"maxAmountToLiquidateUSD":"0x10032432432453"
}
},
"collaterals":{
"ICX":{
"underlyingBalance":"0x365bdc179f420e2eca",
"underlyingBalanceUSD":"0x5c68f6282856c800f6"
},
"USDS":{
"underlyingBalance":"0xade15d8538a814f8d",
"underlyingBalanceUSD":"0xade15d8538a814f8d"
},
"bnUSD":{
"underlyingBalance":"0xead857fc54a25ad9b",
"underlyingBalanceUSD":"0xead857fc54a25ad9b"
}
}
}
Choose which reserve to liquidate, then specify the collateral type you want to take from the borrower after liquidation.
For example, this user borrowed bnUSD and has supplied multiple assets as collateral. To liquidate them in exchange for USDS, you'd use these inputs:
liquidation_data = {'method': 'liquidationCall', 'params': {
'_collateral': 'USDS_TOKEN_ADDRESS',
'_reserve': 'BNUSD_TOKEN_ADDRESS',
'_user': 'hx..',
'_purchaseAmount': 0x10032432432453}}
data = json.dumps(liquidation_data).encode('utf-8')
{
"contract": 'BNUSD_TOKEN_ADDRESS',
"method": "transfer",
"params": {
"_to": 'LENDING_POOL_CONTRACT',
"_value": 0x10032432432453,
"_data": data
}
}
If you have any questions about the liquidation process or need help getting started, join the Omm community on Discord.
Last modified 3mo ago