Non-Auction Liquidations
Step 1: Check if a Position is Liquidatable:
See: Monitoring Position Health.
Step 2: Executing Liquidations
You have two choices of functions to call when executing a liquidation:
liquidate() - Used for maximum liquidations.
Use when:
You want to liquidate the maximum allowed amount.
You don't know the exact optimal amount.
function liquidate(
address[] calldata accounts,
address collateralToken
) external nonReentrant;liquidateExact() - Used for exact amount liquidations.
Use when:
You want to repay an exact amount of debt.
function liquidateExact(
uint256[] calldata debtAmounts,
address[] calldata accounts,
address collateralToken
) external nonReentrant;Token Flows
What the Liquidator Pays:
Liquidator → Debt Token (underlying) → Borrowable cToken
Amount: result.debtRepaidWhat the Liquidator Receives:
Collateral cToken → seize() → Liquidator
Amount: result.liquidatedShares (in cToken shares)Examples
Executing maximum liquidations
// Prepare sorted accounts
const accounts = [
"0x1111111111111111111111111111111111111111",
"0x2222222222222222222222222222222222222222",
"0x3333333333333333333333333333333333333333"
];
// Check liquidation amounts
const debtAmounts = [0, 0, 0];
const action = {
collateralToken: collateralCToken,
debtToken: debtCToken,
numAccounts: 3,
liquidateExact: false,
liquidatedShares: 0,
debtRepaid: 0,
badDebt: 0
};
// Approve total debt to repay
const approveTx = await underlyingDebt.approve(debtCToken, result.debtRepaid);
await approveTx.wait();
// Execute batch liquidation
const liquidateTx = await borrowableCUSDC.liquidate(
accounts,
collateralCToken
);
await liquidateTx.wait();
console.log("All three accounts liquidated in one transaction");
Executing Exact Amount Liquidation
// Liquidate exactly 500 USDC, and store into an array.
const accounts = ["<borrowerAddress>"];
const debtAmounts = [ethers.utils.parseUnits("500", 6)];
// Get underlying debt token
const underlyingDebtAddress = await borrowableCUSDC.asset();
const underlyingDebt = new ethers.Contract(
underlyingDebtAddress,
["function approve(address,uint256) returns (bool)"], // abi
signer
);
// Approve tokens
const approveTx = await underlyingDebt.approve(debtCToken, debtAmounts[0]);
await approveTx.wait();
// Execute exact liquidation
const liquidateTx = await borrowableCUSDC.liquidateExact(
debtAmounts,
accounts,
collateralCToken
);
await liquidateTx.wait();
console.log("Liquidated a single account for an exact amount");Liquidation Tips
Finding Liquidation Opportunities:
Monitor price feeds for significant collateral price drops or debt price increases.
Track accounts with debt close to their maxDebt limit (high-leverage positions).
Focus on volatile collateral assets during market downturns.
Set up event listeners for
Borrowevents to catch new leveraged positions early.
Using Smart Contracts vs Scripts:
Smart contracts are strongly recommended over off-chain scripts for executing liquidations:
Atomic profitability checks - Contract can calculate profit on-chain and revert if unprofitable, saving you from wasting gas on bad liquidations.
Flash loan integration - Borrow capital, liquidate, and repay all in one atomic transaction with zero upfront capital.
Composability - Can integrate with DEX swaps to instantly convert seized collateral to stablecoins.
A typical smart contract liquidator pattern: check profitability → revert if not profitable → execute liquidation → swap collateral → ensure profit threshold met. This guarantees you never execute an unprofitable liquidation.
Last updated