Back to Hub
CREATED BY CHAINLINK LABS

Automated Liquidation Protection

Automatically protect DeFi lending positions by continuously monitoring liquidation risk and executing collateral management, debt repayment, position reduction, or hedging strategies while preserving the confidentiality of centralized exchange as well as LLM API keys, proprietary risk management thresholds, and execution preferences.

What this template does

This CRE workflow implements a confidential liquidation-defense system for DeFi lending positions. It runs on a cron schedule, continuously evaluates a borrower's collateral health, and automatically executes defensive actions before a position reaches the liquidation threshold. Exchange credentials, LLM API keys, risk thresholds, and execution preferences all remain protected inside confidential execution.

Data flow:

  1. Fetch current risk state: collateral and debt pricing, health factor, liquidation proximity, LTV, liquidation threshold, and market volatility.
  2. Load policy parameters from secrets: reserve deployment caps, minimum reserve balance, health factor targets, collateral and repayment limits, sequencing preference, and preferred venues.
  3. Compute a composite risk score from proximity, LTV buffer, health factor, and volatility.
  4. Send risk state and policy to an LLM reasoning model to select and sequence defensive actions.
  5. Enforce all policy constraints against the proposed action plan before execution.
  6. Execute the approved defense plan through the exchange or DeFi API.

If liquidation proximity is above the warning threshold (the position has sufficient buffer), the workflow exits with SAFE and takes no action.

Defensive Actions and Policy Constraints

Defensive action types

ActionDescription
add_collateralDeposit additional collateral directly into the lending position
bridge_and_add_collateralBridge assets from another chain, then deposit as collateral
swap_reserve_to_collateralSwap stablecoin reserves to the collateral asset, then deposit
repay_with_reservesRepay outstanding debt using the stablecoin reserve balance
swap_reserve_to_borrowed_and_repaySwap reserves to the borrowed asset denomination, then repay
partial_debt_repaymentRepay a configured percentage of outstanding debt
full_debt_repaymentRepay the entire outstanding debt balance

Policy constraints

All policy values are loaded from secrets at runtime. Reserve-based constraints are enforced as hard limits before any execution call. Sequencing and venue preferences guide the LLM action plan.

ConstraintDescription
Reserve deployment capMaximum USDC that can be deployed in a single defensive action
Reserve floorMinimum USDC that must remain after any action. Actions that would breach this floor are rejected with an error.
Collateral allocation limitMaximum percentage of available collateral for a single action. Passed to the LLM as a policy parameter.
Partial repayment capMaximum percentage of outstanding debt that can be repaid in a single action
Action sequencingOrder in which defensive moves are prioritized: collateral-first, debt-first, or balanced
Preferred venuesComma-separated list of preferred execution venues (e.g., binance,onchain,coinbase)

Risk signals monitored

SignalDescription
liquidation_proximity_pctPercentage buffer distance from the liquidation threshold (higher = more buffer = safer)
collateral_health_factorRatio of collateral value to outstanding debt
loan_to_value_pctCurrent LTV percentage
liquidation_threshold_pctProtocol-defined liquidation threshold
volatility_indexMarket volatility indicator

Risk score

The workflow computes a composite risk score to guide action selection:

proximityRisk  = max(0, warningThreshold − liquidationProximity) × 5
ltvBufferRisk  = max(0, LTV − (liquidationThreshold − 5)) × 2
healthRisk     = max(0, minHealthFactor − healthFactor) × 100
volatilityRisk = volatilityIndex × 25
riskScore      = proximityRisk + ltvBufferRisk + healthRisk + volatilityRisk

Prerequisites

  • Bun runtime
  • CRE CLI (cre)
  • A DeFi risk monitoring or exchange API that exposes position health signals
  • An LLM API endpoint for reasoning (e.g., an OpenAI-compatible endpoint)

Configuration

The workflow ships with two config files:

  • automated-liquidation-protection-ts/config.staging.json (TypeScript) and automated-liquidation-protection-go/config.staging.json (Go): targets mock server endpoints
  • automated-liquidation-protection-ts/config.production.json (TypeScript) and automated-liquidation-protection-go/config.production.json (Go): same structure with empty URLs for you to populate

Key fields:

FieldDescription
scheduleCron expression. Default: 0 */5 * * * * (every 5 minutes)
mock_base_urlBase URL for the exchange or risk API
openai_urlLLM reasoning endpoint
openai_modelModel identifier (e.g., gpt-4.1-mini)
secrets_ids.*Secret IDs for API keys and all policy parameters

Secrets

Copy .env.example to .env and populate all values before running locally. The workflow enforces a strict limit of exactly 11 secrets per invocation.

Environment variableSecret IDPurpose
MOCK_EXCHANGE_API_KEYexchange_api_keyAuthenticates exchange or risk API requests
MOCK_OPENAI_API_KEYopenai_api_keyAuthenticates LLM reasoning API requests
MOCK_LIQUIDATION_WARNING_ACTION_THRESHOLDliquidation_liquidation_warning_action_thresholdProximity percentage that triggers defensive actions (e.g., 18)
MOCK_LIQUIDATION_MINIMUM_HEALTH_FACTORliquidation_minimum_health_factorMinimum acceptable health factor (e.g., 1.25)
MOCK_LIQUIDATION_TARGET_HEALTH_FACTORliquidation_target_health_factorTarget health factor after defense executes (e.g., 1.5)
MOCK_LIQUIDATION_MAX_STABLECOIN_RESERVE_DEPLOYMENTliquidation_maximum_stablecoin_reserve_deploymentMaximum USDC that can be deployed per action (e.g., 5000)
MOCK_LIQUIDATION_MIN_STABLECOIN_RESERVE_BALANCEliquidation_minimum_stablecoin_reserve_balanceMinimum USDC to keep in reserve (e.g., 2000)
MOCK_LIQUIDATION_MAX_COLLATERAL_ALLOCATIONliquidation_maximum_collateral_allocationMaximum collateral percentage per action (e.g., 80)
MOCK_LIQUIDATION_MAX_PARTIAL_DEBT_REPAYMENTliquidation_maximum_partial_debt_repaymentMaximum debt repayment percentage per action (e.g., 40)
MOCK_LIQUIDATION_DEFENSIVE_ACTION_SEQUENCING_PREFERENCEliquidation_defensive_action_sequencing_preferencecollateral-first, debt-first, or balanced
MOCK_LIQUIDATION_PREFERRED_VENUESliquidation_preferred_venuesComma-separated venue list (e.g., binance,onchain,coinbase)
CRE_ETH_PRIVATE_KEY(framework-level)Optional for local simulation. Required if executing on-chain actions.

Quick start

TypeScript

Run all commands from the automated-liquidation-protection directory (the project root).

  1. Install dependencies

    cd automated-liquidation-protection-ts && bun install && cd ..
    
  2. Create environment file

    cp .env.example .env
    
  3. Start mock server

    cd automated-liquidation-protection-ts && bun run mock:server
    
  4. In another terminal, run checks and simulate

    cd automated-liquidation-protection-ts
    bun run typecheck
    bun run test
    cd .. && cre workflow simulate ./automated-liquidation-protection-ts --project-root ./ --target=staging-settings --env ./.env
    

Go

Run all commands from the automated-liquidation-protection directory (the project root).

  1. Create environment file

    cp .env.example .env
    
  2. Start the mock server from the TypeScript directory (requires Node or Bun)

    cd automated-liquidation-protection-ts && bun run mock:server
    
  3. In another terminal, run checks and simulate

    cd automated-liquidation-protection-go
    go vet ./...
    go test ./...
    cd .. && cre workflow simulate ./automated-liquidation-protection-go --project-root ./ --target=staging-settings --env ./.env
    

Production checklist

  • Populate config.production.json with real mock_base_url and openai_url.
  • Register all 11 secrets in the CRE secrets manager and verify secret IDs match those defined in config.production.json under secrets_ids.
  • Set MOCK_LIQUIDATION_MIN_STABLECOIN_RESERVE_BALANCE to a value that provides a meaningful reserve buffer for your position size.
  • Set CRE_ETH_PRIVATE_KEY if any defensive action routes through on-chain execution.
  • Confirm the exchange API returns the expected risk state schema before deploying.
  • Run bun run typecheck && bun run test (TypeScript) or go vet ./... && go test ./... (Go) before registering.
  • Run cre workflow simulate against production endpoints to validate end-to-end behavior.
  • Register the workflow:
    • TypeScript: cre workflow register ./automated-liquidation-protection-ts --project-root ./ --target=production-settings
    • Go: cre workflow register ./automated-liquidation-protection-go --project-root ./ --target=production-settings

Troubleshooting

Reserve floor breach error

If you see action X breaches reserve floor: projected Y < floor Z, the proposed action would reduce stablecoin reserves below the configured minimum. Increase MOCK_LIQUIDATION_MIN_STABLECOIN_RESERVE_BALANCE, reduce MOCK_LIQUIDATION_MAX_STABLECOIN_RESERVE_DEPLOYMENT, or reduce position size.

Secrets must be finite numbers

If you see secret X must be a finite number, one of the numeric policy secrets was set to a non-numeric value. Confirm that all numeric environment variables in .env are valid floats or integers (e.g., 1.25, not "n/a").

LLM response format mismatch

If the LLM response cannot be parsed, the model must return either an output_text field or a nested output[].content[].text structure. If neither is present, you will see the error openai response did not contain output_text. Check your LLM endpoint logs or mock server configuration to verify the response format.

HTTP request failures

If you see request failed status=4XX, confirm the mock server is running (bun run mock:server) and that the API keys in .env match the values expected by the mock server.

Workflow logs liquidation-no-action

This is expected behavior when the position is healthy. The log includes proximity=X threshold=Y reason=Z to confirm the position state and why no action was taken.

Get the latest Chainlink content straight to your inbox.