Source Code

;; Liquidity Pool Contract
;; Simplified peer-to-peer lending pool with dynamic rates

;; Constants
(define-constant contract-owner tx-sender)
(define-constant err-owner-only (err u500))
(define-constant err-insufficient-liquidity (err u501))
(define-constant err-insufficient-balance (err u502))
(define-constant err-invalid-amount (err u503))
(define-constant err-pool-paused (err u504))

;; Pool parameters
(define-constant base-rate u500) ;; 5% base APY

;; Data Variables
(define-data-var pool-paused bool false)
(define-data-var borrow-nonce uint u0)

;; Data Maps
(define-map liquidity-providers
  { provider: principal }
  {
    deposited: uint,
    available: uint,
    earned: uint
  }
)

(define-map pool-borrows
  { borrower: principal, borrow-id: uint }
  {
    amount: uint,
    lender: principal,
    interest-rate: uint,
    borrow-block: uint,
    repaid: bool
  }
)

;; Read-only functions
(define-read-only (get-lp-info (provider principal))
  (default-to
    { deposited: u0, available: u0, earned: u0 }
    (map-get? liquidity-providers { provider: provider })
  )
)

(define-read-only (get-borrow-info (borrower principal) (borrow-id uint))
  (map-get? pool-borrows { borrower: borrower, borrow-id: borrow-id })
)

(define-read-only (get-current-rate)
  (ok base-rate)
)

;; Public functions

;; Deposit STX to pool
(define-public (deposit-to-pool (amount uint))
  (let
    (
      (lp-info (get-lp-info tx-sender))
    )
    (asserts! (not (var-get pool-paused)) err-pool-paused)
    (asserts! (> amount u0) err-invalid-amount)
    
    (map-set liquidity-providers
      { provider: tx-sender }
      {
        deposited: (+ (get deposited lp-info) amount),
        available: (+ (get available lp-info) amount),
        earned: (get earned lp-info)
      }
    )
    
    (ok amount)
  )
)

;; Borrow from specific lender
(define-public (borrow-from-pool (amount uint) (lender principal))
  (let
    (
      (borrow-id (var-get borrow-nonce))
      (current-rate (unwrap! (get-current-rate) err-invalid-amount))
      (lender-info (get-lp-info lender))
    )
    (asserts! (not (var-get pool-paused)) err-pool-paused)
    (asserts! (> amount u0) err-invalid-amount)
    (asserts! (>= (get available lender-info) amount) err-insufficient-liquidity)
    
    (try! (stx-transfer? amount lender tx-sender))
    
    (map-set liquidity-providers
      { provider: lender }
      (merge lender-info { available: (- (get available lender-info) amount) })
    )
    
    (map-set pool-borrows
      { borrower: tx-sender, borrow-id: borrow-id }
      {
        amount: amount,
        lender: lender,
        interest-rate: current-rate,
        borrow-block: stacks-block-height,
        repaid: false
      }
    )
    
    (var-set borrow-nonce (+ borrow-id u1))
    (ok borrow-id)
  )
)

;; Repay pool borrow
(define-public (repay-pool-borrow (borrow-id uint))
  (let
    (
      (borrow-info (unwrap! (get-borrow-info tx-sender borrow-id) err-invalid-amount))
      (principal-amount (get amount borrow-info))
      (lender (get lender borrow-info))
      (blocks-elapsed (- stacks-block-height (get borrow-block borrow-info)))
      (interest-rate (get interest-rate borrow-info))
      (interest (/ (* (* principal-amount interest-rate) blocks-elapsed) u525600000))
      (total-repayment (+ principal-amount interest))
      (lender-info (get-lp-info lender))
    )
    (asserts! (not (get repaid borrow-info)) err-invalid-amount)
    
    (try! (stx-transfer? total-repayment tx-sender lender))
    
    (map-set liquidity-providers
      { provider: lender }
      {
        deposited: (get deposited lender-info),
        available: (+ (get available lender-info) principal-amount),
        earned: (+ (get earned lender-info) interest)
      }
    )
    
    (map-set pool-borrows
      { borrower: tx-sender, borrow-id: borrow-id }
      (merge borrow-info { repaid: true })
    )
    
    (ok total-repayment)
  )
)

;; Withdraw from pool
(define-public (withdraw-from-pool (amount uint))
  (let
    (
      (lp-info (get-lp-info tx-sender))
    )
    (asserts! (not (var-get pool-paused)) err-pool-paused)
    (asserts! (<= amount (get available lp-info)) err-insufficient-balance)
    
    (map-set liquidity-providers
      { provider: tx-sender }
      {
        deposited: (- (get deposited lp-info) amount),
        available: (- (get available lp-info) amount),
        earned: (get earned lp-info)
      }
    )
    
    (ok amount)
  )
)

;; Pause pool (owner only)
(define-public (pause-pool)
  (begin
    (asserts! (is-eq tx-sender contract-owner) err-owner-only)
    (var-set pool-paused true)
    (ok true)
  )
)

;; Unpause pool (owner only)
(define-public (unpause-pool)
  (begin
    (asserts! (is-eq tx-sender contract-owner) err-owner-only)
    (var-set pool-paused false)
    (ok true)
  )
)

Functions (9)

FunctionAccessArgs
get-lp-inforead-onlyprovider: principal
get-borrow-inforead-onlyborrower: principal, borrow-id: uint
get-current-rateread-only
deposit-to-poolpublicamount: uint
borrow-from-poolpublicamount: uint, lender: principal
repay-pool-borrowpublicborrow-id: uint
withdraw-from-poolpublicamount: uint
pause-poolpublic
unpause-poolpublic