Source Code

;; DeFi Lending Pool Contract
;; Enables collateralized lending and borrowing of STX and SIP-010 tokens

;; Constants
(define-constant contract-owner tx-sender)
(define-constant err-owner-only (err u100))
(define-constant err-insufficient-collateral (err u101))
(define-constant err-insufficient-liquidity (err u102))
(define-constant err-loan-not-found (err u103))
(define-constant err-invalid-amount (err u104))
(define-constant err-already-liquidated (err u105))

;; Data Variables
(define-data-var total-deposits uint u0)
(define-data-var total-borrows uint u0)
(define-data-var collateral-ratio uint u150) ;; 150% collateralization required
(define-data-var paused bool false)

;; Data Maps
(define-map user-deposits principal uint)
(define-map user-collateral principal uint)
(define-map user-borrows principal uint)
(define-map loan-details 
  uint 
  {
    borrower: principal,
    collateral-amount: uint,
    borrow-amount: uint,
    interest-rate: uint,
    timestamp: uint,
    liquidated: bool
  }
)

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

;; Read-only functions
(define-read-only (get-pool-info)
  {
    total-deposits: (var-get total-deposits),
    total-borrows: (var-get total-borrows),
    available-liquidity: (- (var-get total-deposits) (var-get total-borrows)),
    collateral-ratio: (var-get collateral-ratio)
  }
)

(define-read-only (get-user-deposits (user principal))
  (default-to u0 (map-get? user-deposits user))
)

(define-read-only (get-user-collateral (user principal))
  (default-to u0 (map-get? user-collateral user))
)

(define-read-only (get-user-borrows (user principal))
  (default-to u0 (map-get? user-borrows user))
)

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

(define-read-only (calculate-max-borrow (collateral-amount uint))
  (/ (* collateral-amount u100) (var-get collateral-ratio))
)

;; Public functions
(define-public (deposit (amount uint))
  (begin
    (asserts! (not (var-get paused)) (err u106))
    (asserts! (> amount u0) err-invalid-amount)
    
    (try! (stx-transfer? amount tx-sender (as-contract tx-sender)))
    
    (map-set user-deposits tx-sender 
      (+ (get-user-deposits tx-sender) amount))
    (var-set total-deposits (+ (var-get total-deposits) amount))
    
    (ok amount)
  )
)

(define-public (withdraw (amount uint))
  (let (
    (user-balance (get-user-deposits tx-sender))
  )
    (asserts! (not (var-get paused)) (err u106))
    (asserts! (>= user-balance amount) err-insufficient-liquidity)
    
    (try! (as-contract (stx-transfer? amount tx-sender tx-sender)))
    
    (map-set user-deposits tx-sender (- user-balance amount))
    (var-set total-deposits (- (var-get total-deposits) amount))
    
    (ok amount)
  )
)

(define-public (deposit-collateral (amount uint))
  (begin
    (asserts! (not (var-get paused)) (err u106))
    (asserts! (> amount u0) err-invalid-amount)
    
    (try! (stx-transfer? amount tx-sender (as-contract tx-sender)))
    
    (map-set user-collateral tx-sender 
      (+ (get-user-collateral tx-sender) amount))
    
    (ok amount)
  )
)

(define-public (borrow (amount uint))
  (let (
    (user-collateral-amount (get-user-collateral tx-sender))
    (max-borrow (calculate-max-borrow user-collateral-amount))
    (current-borrows (get-user-borrows tx-sender))
    (available-liquidity (- (var-get total-deposits) (var-get total-borrows)))
    (loan-id (var-get next-loan-id))
  )
    (asserts! (not (var-get paused)) (err u106))
    (asserts! (> amount u0) err-invalid-amount)
    (asserts! (>= max-borrow (+ current-borrows amount)) err-insufficient-collateral)
    (asserts! (>= available-liquidity amount) err-insufficient-liquidity)
    
    (try! (as-contract (stx-transfer? amount tx-sender tx-sender)))
    
    (map-set user-borrows tx-sender (+ current-borrows amount))
    (var-set total-borrows (+ (var-get total-borrows) amount))
    
    (map-set loan-details loan-id {
      borrower: tx-sender,
      collateral-amount: user-collateral-amount,
      borrow-amount: amount,
      interest-rate: u5,
      timestamp: block-height,
      liquidated: false
    })
    
    (var-set next-loan-id (+ loan-id u1))
    
    (ok loan-id)
  )
)

(define-public (repay (amount uint))
  (let (
    (current-borrows (get-user-borrows tx-sender))
  )
    (asserts! (not (var-get paused)) (err u106))
    (asserts! (> amount u0) err-invalid-amount)
    (asserts! (>= current-borrows amount) (err u107))
    
    (try! (stx-transfer? amount tx-sender (as-contract tx-sender)))
    
    (map-set user-borrows tx-sender (- current-borrows amount))
    (var-set total-borrows (- (var-get total-borrows) amount))
    
    (ok amount)
  )
)

(define-public (withdraw-collateral (amount uint))
  (let (
    (user-collateral-amount (get-user-collateral tx-sender))
    (current-borrows (get-user-borrows tx-sender))
    (remaining-collateral (- user-collateral-amount amount))
    (required-collateral (/ (* current-borrows (var-get collateral-ratio)) u100))
  )
    (asserts! (not (var-get paused)) (err u106))
    (asserts! (>= user-collateral-amount amount) err-insufficient-collateral)
    (asserts! (>= remaining-collateral required-collateral) err-insufficient-collateral)
    
    (try! (as-contract (stx-transfer? amount tx-sender tx-sender)))
    
    (map-set user-collateral tx-sender remaining-collateral)
    
    (ok amount)
  )
)

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

(define-public (toggle-pause)
  (begin
    (asserts! (is-eq tx-sender contract-owner) err-owner-only)
    (var-set paused (not (var-get paused)))
    (ok (var-get paused))
  )
)

Functions (14)

FunctionAccessArgs
get-pool-inforead-only
get-user-depositsread-onlyuser: principal
get-user-collateralread-onlyuser: principal
get-user-borrowsread-onlyuser: principal
get-loan-detailsread-onlyloan-id: uint
calculate-max-borrowread-onlycollateral-amount: uint
depositpublicamount: uint
withdrawpublicamount: uint
deposit-collateralpublicamount: uint
borrowpublicamount: uint
repaypublicamount: uint
withdraw-collateralpublicamount: uint
set-collateral-ratiopublicnew-ratio: uint
toggle-pausepublic