Source Code

(define-constant contract-owner tx-sender)
(define-constant err-owner-only (err u100))
(define-constant err-not-found (err u101))
(define-constant err-insufficient-balance (err u102))
(define-constant err-loan-active (err u103))

(define-map loans
  uint
  {
    borrower: principal,
    lender: principal,
    principal-amount: uint,
    interest-rate: uint,
    duration-blocks: uint,
    start-block: uint,
    repaid: bool
  })

(define-map liquidity-pool principal uint)

(define-data-var next-loan-id uint u0)
(define-data-var total-liquidity uint u0)

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

(define-read-only (get-liquidity (provider principal))
  (ok (default-to u0 (map-get? liquidity-pool provider))))

(define-public (provide-liquidity (amount uint))
  (begin
    (try! (stx-transfer? amount tx-sender (as-contract tx-sender)))
    (map-set liquidity-pool tx-sender
      (+ (default-to u0 (map-get? liquidity-pool tx-sender)) amount))
    (var-set total-liquidity (+ (var-get total-liquidity) amount))
    (ok true)))

(define-public (withdraw-liquidity (amount uint))
  (let ((balance (default-to u0 (map-get? liquidity-pool tx-sender))))
    (asserts! (>= balance amount) err-insufficient-balance)
    (try! (stx-transfer? amount tx-sender (as-contract tx-sender)))
    (map-set liquidity-pool tx-sender (- balance amount))
    (var-set total-liquidity (- (var-get total-liquidity) amount))
    (ok true)))

(define-public (request-loan (amount uint) (rate uint) (duration uint))
  (let ((loan-id (var-get next-loan-id)))
    (asserts! (<= amount (var-get total-liquidity)) err-insufficient-balance)
    (try! (stx-transfer? amount tx-sender (as-contract tx-sender)))
    (map-set loans loan-id
      {borrower: tx-sender, lender: contract-owner, principal-amount: amount,
       interest-rate: rate, duration-blocks: duration, start-block: stacks-block-height, repaid: false})
    (var-set next-loan-id (+ loan-id u1))
    (var-set total-liquidity (- (var-get total-liquidity) amount))
    (ok loan-id)))

(define-public (repay-loan (loan-id uint))
  (let ((loan (unwrap! (map-get? loans loan-id) err-not-found))
        (interest (/ (* (get principal-amount loan) (get interest-rate loan)) u10000))
        (total-repayment (+ (get principal-amount loan) interest)))
    (asserts! (is-eq tx-sender (get borrower loan)) err-owner-only)
    (asserts! (not (get repaid loan)) err-loan-active)
    (try! (stx-transfer? total-repayment tx-sender (as-contract tx-sender)))
    (map-set loans loan-id (merge loan {repaid: true}))
    (var-set total-liquidity (+ (var-get total-liquidity) total-repayment))
    (ok true)))

Functions (6)

FunctionAccessArgs
get-loanread-onlyloan-id: uint
get-liquidityread-onlyprovider: principal
provide-liquiditypublicamount: uint
withdraw-liquiditypublicamount: uint
request-loanpublicamount: uint, rate: uint, duration: uint
repay-loanpublicloan-id: uint