fractional-reserve-fungible-token

SP1V95DB4JK47QVPJBXCEN6MT35JK84CQ4CWS15DQ

Source Code

(define-constant CONTRACT_OWNER tx-sender)
(define-constant ERR_NOT_AUTHORIZED (err u1500))
(define-constant ERR_INSUFFICIENT_RESERVE (err u1501))
(define-constant ERR_INVALID_RATIO (err u1502))

(define-fungible-token fractional-reserve-token)

(define-data-var required-reserve-ratio uint u50)
(define-data-var total-reserve uint u0)
(define-data-var total-borrowed uint u0)

(define-map segregated-balances
  principal
  {normal-balance: uint, borrowed-balance: uint}
)

(define-map reserve-deposits
  principal
  uint
)

(define-read-only (get-contract-hash)
  (contract-hash? .fractional-reserve-fungible-token)
)

(define-read-only (get-balance (account principal))
  (ok (ft-get-balance fractional-reserve-token account))
)

(define-read-only (get-total-supply)
  (ok (ft-get-supply fractional-reserve-token))
)

(define-read-only (get-required-reserve-ratio)
  (ok (var-get required-reserve-ratio))
)

(define-read-only (get-segregated-balance (account principal))
  (ok (default-to {normal-balance: u0, borrowed-balance: u0} (map-get? segregated-balances account)))
)

(define-public (set-reserve-ratio (new-ratio uint))
  (begin
    (asserts! (is-eq tx-sender CONTRACT_OWNER) ERR_NOT_AUTHORIZED)
    (asserts! (<= new-ratio u100) ERR_INVALID_RATIO)
    (var-set required-reserve-ratio new-ratio)
    (ok true)
  )
)

(define-public (fractional-reserve-mint (amount uint) (recipient principal))
  (let
    (
      (current-reserve (var-get total-reserve))
      (required-reserve (/ (* amount (var-get required-reserve-ratio)) u100))
    )
    (asserts! (is-eq tx-sender CONTRACT_OWNER) ERR_NOT_AUTHORIZED)
    (asserts! (>= current-reserve required-reserve) ERR_INSUFFICIENT_RESERVE)
    (try! (ft-mint? fractional-reserve-token amount recipient))
    (let
      (
        (account-data (default-to {normal-balance: u0, borrowed-balance: u0} (map-get? segregated-balances recipient)))
      )
      (map-set segregated-balances recipient (merge account-data {
        normal-balance: (+ (get normal-balance account-data) amount)
      }))
    )
    (ok true)
  )
)

(define-public (fractional-reserve-burn (amount uint))
  (let
    (
      (account-data (default-to {normal-balance: u0, borrowed-balance: u0} (map-get? segregated-balances tx-sender)))
    )
    (asserts! (>= (ft-get-balance fractional-reserve-token tx-sender) amount) ERR_INSUFFICIENT_RESERVE)
    (try! (ft-burn? fractional-reserve-token amount tx-sender))
    (map-set segregated-balances tx-sender (merge account-data {
      normal-balance: (if (>= (get normal-balance account-data) amount)
        (- (get normal-balance account-data) amount)
        u0)
    }))
    (ok true)
  )
)

(define-public (deposit-reserve (amount uint))
  (begin
    (try! (stx-transfer? amount tx-sender CONTRACT_OWNER))
    (var-set total-reserve (+ (var-get total-reserve) amount))
    (map-set reserve-deposits tx-sender 
      (+ (default-to u0 (map-get? reserve-deposits tx-sender)) amount)
    )
    (ok true)
  )
)

(define-public (withdraw-reserve (amount uint))
  (let
    (
      (deposited (default-to u0 (map-get? reserve-deposits tx-sender)))
    )
    (asserts! (>= deposited amount) ERR_INSUFFICIENT_RESERVE)
    (try! (stx-transfer? amount CONTRACT_OWNER tx-sender))
    (var-set total-reserve (- (var-get total-reserve) amount))
    (map-set reserve-deposits tx-sender (- deposited amount))
    (ok true)
  )
)

(define-public (mint-borrowed (amount uint) (recipient principal))
  (let
    (
      (current-reserve (var-get total-reserve))
      (required-reserve (/ (* amount (var-get required-reserve-ratio)) u100))
    )
    (asserts! (is-eq tx-sender CONTRACT_OWNER) ERR_NOT_AUTHORIZED)
    (asserts! (>= current-reserve required-reserve) ERR_INSUFFICIENT_RESERVE)
    (try! (ft-mint? fractional-reserve-token amount recipient))
    (var-set total-borrowed (+ (var-get total-borrowed) amount))
    (let
      (
        (account-data (default-to {normal-balance: u0, borrowed-balance: u0} (map-get? segregated-balances recipient)))
      )
      (map-set segregated-balances recipient (merge account-data {
        borrowed-balance: (+ (get borrowed-balance account-data) amount)
      }))
    )
    (ok true)
  )
)

(define-public (transfer (amount uint) (sender principal) (recipient principal))
  (begin
    (asserts! (is-eq tx-sender sender) ERR_NOT_AUTHORIZED)
    (ft-transfer? fractional-reserve-token amount sender recipient)
  )
)

(define-read-only (verify-secp256r1-signature (message (buff 32)) (signature (buff 64)) (public-key (buff 33)))
  (ok (secp256r1-verify message signature public-key))
)

(define-read-only (get-block-time)
  stacks-block-time
)

(define-read-only (asset-check)
  (ok (is-ok (contract-hash? .fractional-reserve-fungible-token)))
)

Functions (15)

FunctionAccessArgs
get-contract-hashread-only
get-balanceread-onlyaccount: principal
get-total-supplyread-only
get-required-reserve-ratioread-only
get-segregated-balanceread-onlyaccount: principal
set-reserve-ratiopublicnew-ratio: uint
fractional-reserve-mintpublicamount: uint, recipient: principal
fractional-reserve-burnpublicamount: uint
deposit-reservepublicamount: uint
withdraw-reservepublicamount: uint
mint-borrowedpublicamount: uint, recipient: principal
transferpublicamount: uint, sender: principal, recipient: principal
verify-secp256r1-signatureread-onlymessage: (buff 32
get-block-timeread-only
asset-checkread-only