Make a liquidation bot!

GLOW Protocol Liquidation Guide

Overview

GLOW Protocol uses the same liquidation system as Gearbox Protocol. When glow accounts become unhealthy (Health Factor < 1.0), they can be liquidated by anyone to maintain protocol stability and earn rewards.

When Can an Account Be Liquidated?

A glow account becomes eligible for liquidation when:

  • Health Factor < 1.0 - The account's collateral value falls below the liquidation threshold

Health Factor Calculation

Health Factor = (Total Collateral Value × Liquidation Threshold) / Total Debt

Liquidation Function

function liquidateCreditAccount(
    address creditAccount,
    address to,
    MultiCall[] calldata calls
) external payable;
Parameter
Description

creditAccount

The address of the glow account to liquidate

to

Address to transfer leftover underlying tokens after liquidation

calls

Array of MultiCall structs to execute during liquidation

Finding Liquidatable Accounts

The DataCompressor contract provides efficient bulk queries to find liquidatable accounts:

// From dc.sol - Gets all liquidatable accounts
function getLiquidatableCreditAccounts(
    PriceOnDemand[] memory priceUpdates
) external view returns (CreditAccountData[] memory result);

// Internal function that checks if an account is liquidatable
function _queryCreditAccounts(
    address[] memory creditManagers,
    address borrower,
    bool liquidatableOnly,
    PriceOnDemand[] memory priceUpdates
) public view returns (CreditAccountData[] memory result) {
    // ... iteration logic ...
    
    if (liquidatableOnly) {
        try
            ICreditManagerV3(_cm).isLiquidatable(
                creditAccounts[j],
                PERCENTAGE_FACTOR  // 10000 = 100% = 1.0 HF threshold
            )
        returns (bool isLiquidatable) {
            if (!isLiquidatable) continue;
        } catch {}
    }
    
    // ... rest of function ...
}

Using CreditManager Directly

// Check if account is liquidatable
bool isLiquidatable = creditManager.isLiquidatable(creditAccount, 10000);

// Get detailed account data
(uint256 debt, uint256 collateral, uint256 healthFactor) = 
    creditManager.calcDebtAndCollateral(creditAccount);

JavaScript Implementation

// Get all liquidatable accounts
async function getLiquidatableAccounts() {
    const dataCompressor = new ethers.Contract(
        DATA_COMPRESSOR_ADDRESS,
        dataCompressorAbi,
        provider
    );
    
    return await dataCompressor.getLiquidatableCreditAccounts([]);
}

// Check specific account
async function isAccountLiquidatable(creditManager, creditAccount) {
    const cm = new ethers.Contract(creditManager, creditManagerAbi, provider);
    return await cm.isLiquidatable(creditAccount, 10000);
}

Basic Liquidation Strategies

Strategy 1: Convert Collateral to Underlying

// Swap all collateral tokens to underlying via DEX
const calls = [
    {
        target: UNISWAP_ROUTER,
        callData: swapExactTokensForTokens(
            tokenBalance,
            minAmountOut,
            [collateralToken, underlyingToken],
            creditAccount,
            deadline
        )
    }
];

Strategy 2: Add Underlying (+ Withdraw Assets, not always needed)

// Add underlying to cover debt, then withdraw valuable collateral
const calls = [
    {
        target: creditAccount,
        callData: addCollateralCalldata(underlyingToken, debtAmount)
    },
    {
        target: creditAccount, 
        callData: withdrawTokenCalldata(valuableToken, amount)
    }
];

Contract Addresses (PulseChain)

Core Contracts

Basic Liquidation Bot

class GLOWLiquidationBot {
    async monitorAndLiquidate() {
        // Get all liquidatable accounts
        const accounts = await this.dataCompressor.getLiquidatableCreditAccounts([]);
        
        for (const account of accounts) {
            if (await this.isProfitable(account)) {
                await this.liquidate(account);
            }
        }
    }
    
    async isProfitable(account) {
        const liquidationPremium = account.totalDebt * 0.05; // 5%
        const gasCost = 500000 * gasPrice;
        return liquidationPremium > gasCost;
    }
    
    async liquidate(account) {
        const strategy = await this.calculateOptimalStrategy(account);
        
        await this.creditFacade.liquidateCreditAccount(
            account.addr,
            this.address,
            strategy.calls
        );
    }
}

Important Notes

  • Test First: Always test on testnet before mainnet

  • Account for Slippage: Add 2-5% buffer for DEX trades

  • Monitor Gas: Ensure profits exceed transaction costs

  • Competition: Use higher gas prices for time-sensitive liquidations

  • Risk Management: Start small and understand the mechanics

Resources

  • GLOW Dashboard: Monitor liquidatable accounts in real-time

  • Documentation: https://nexion-1.gitbook.io/nexion/glow/glow-protocol

  • PulseChain Explorer: https://otter.pulsechain.com

If you need more help speak to our dev in telegram http://t.me/Lefkk or join our group @NexionPulse

Last updated