Source Code

;; Liquidation Engine Contract
;; Handles liquidation of undercollateralized positions

;; Constants
(define-constant contract-owner tx-sender)
(define-constant err-owner-only (err u100))
(define-constant err-not-liquidatable (err u101))
(define-constant err-invalid-amount (err u102))
(define-constant err-already-liquidated (err u103))

;; Data Variables
(define-data-var liquidation-threshold uint u120) ;; 120% threshold
(define-data-var liquidation-bonus uint u10) ;; 10% bonus for liquidators
(define-data-var max-liquidation-close uint u50) ;; Max 50% of debt can be liquidated

;; Data Maps
(define-map liquidation-history 
  uint 
  {
    liquidator: principal,
    borrower: principal,
    collateral-seized: uint,
    debt-repaid: uint,
    timestamp: uint
  }
)

(define-data-var next-liquidation-id uint u1)

;; Read-only functions
(define-read-only (get-liquidation-threshold)
  (var-get liquidation-threshold)
)

(define-read-only (is-liquidatable (collateral uint) (debt uint))
  (let (
    (collateral-value collateral)
    (debt-value debt)
    (health-factor (if (is-eq debt-value u0)
                     u1000
                     (/ (* collateral-value u100) debt-value)))
  )
    (< health-factor (var-get liquidation-threshold))
  )
)

(define-read-only (calculate-liquidation-amount (debt uint))
  (/ (* debt (var-get max-liquidation-close)) u100)
)

(define-read-only (calculate-collateral-to-seize (debt-to-cover uint) (collateral-price uint))
  (let (
    (base-collateral (/ debt-to-cover collateral-price))
    (bonus-amount (/ (* base-collateral (var-get liquidation-bonus)) u100))
  )
    (+ base-collateral bonus-amount)
  )
)

(define-read-only (get-liquidation-details (liquidation-id uint))
  (map-get? liquidation-history liquidation-id)
)

;; Public functions
(define-public (liquidate (borrower principal) (debt-to-cover uint))
  (let (
    (liquidation-id (var-get next-liquidation-id))
    ;; In production, these would come from oracle or lending pool
    (borrower-collateral u1000000)
    (borrower-debt u900000)
  )
    (asserts! (> debt-to-cover u0) err-invalid-amount)
    (asserts! (is-liquidatable borrower-collateral borrower-debt) err-not-liquidatable)
    
    (let (
      (max-liquidation (calculate-liquidation-amount borrower-debt))
      (actual-debt-to-cover (if (<= debt-to-cover max-liquidation)
                              debt-to-cover
                              max-liquidation))
      (collateral-to-seize (calculate-collateral-to-seize actual-debt-to-cover u1))
    )
      ;; Transfer debt payment from liquidator
      (try! (stx-transfer? actual-debt-to-cover tx-sender (as-contract tx-sender)))
      
      ;; Transfer collateral to liquidator
      (try! (as-contract (stx-transfer? collateral-to-seize tx-sender tx-sender)))
      
      ;; Record liquidation
      (map-set liquidation-history liquidation-id {
        liquidator: tx-sender,
        borrower: borrower,
        collateral-seized: collateral-to-seize,
        debt-repaid: actual-debt-to-cover,
        timestamp: block-height
      })
      
      (var-set next-liquidation-id (+ liquidation-id u1))
      
      (ok {
        liquidation-id: liquidation-id,
        collateral-seized: collateral-to-seize,
        debt-repaid: actual-debt-to-cover
      })
    )
  )
)

;; Admin functions
(define-public (update-liquidation-threshold (new-threshold uint))
  (begin
    (asserts! (is-eq tx-sender contract-owner) err-owner-only)
    (var-set liquidation-threshold new-threshold)
    (ok true)
  )
)

(define-public (update-liquidation-bonus (new-bonus uint))
  (begin
    (asserts! (is-eq tx-sender contract-owner) err-owner-only)
    (var-set liquidation-bonus new-bonus)
    (ok true)
  )
)

(define-public (update-max-liquidation-close (new-max uint))
  (begin
    (asserts! (is-eq tx-sender contract-owner) err-owner-only)
    (asserts! (<= new-max u100) err-invalid-amount)
    (var-set max-liquidation-close new-max)
    (ok true)
  )
)

Functions (9)

FunctionAccessArgs
get-liquidation-thresholdread-only
is-liquidatableread-onlycollateral: uint, debt: uint
calculate-liquidation-amountread-onlydebt: uint
calculate-collateral-to-seizeread-onlydebt-to-cover: uint, collateral-price: uint
get-liquidation-detailsread-onlyliquidation-id: uint
liquidatepublicborrower: principal, debt-to-cover: uint
update-liquidation-thresholdpublicnew-threshold: uint
update-liquidation-bonuspublicnew-bonus: uint
update-max-liquidation-closepublicnew-max: uint