# Non-Auction Liquidations

### Step 1: Check if a Position is Liquidatable:

**See:** [Monitoring Position Health](https://docs.curvance.com/cve/developer-docs/quick-start-guides/leverage#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.

```solidity
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.

```solidity
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.debtRepaid
```

**What the Liquidator Receives:**

```
Collateral cToken → seize() → Liquidator
Amount: result.liquidatedShares (in cToken shares)
```

#### Examples

**Executing maximum liquidations**

```javascript
  // 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**

```javascript
  // 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 `Borrow` events 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.
