Source Code

;; Contains all state for freddie the vault manager

;; ---------------------------------------------------------
;; Variables
;; ---------------------------------------------------------

;; Map of vault entries
;; The entry consists of a user principal with their collateral and debt balance
(define-map vaults { id: uint } {
  id: uint,
  owner: principal,
  collateral: uint,
  collateral-type: (string-ascii 12), ;; e.g. STX-A, STX-B, BTC-A etc (represents the collateral class)
  collateral-token: (string-ascii 12), ;; e.g. STX, BTC etc (represents the symbol of the collateral)
  stacked-tokens: uint,
  revoked-stacking: bool,
  auto-payoff: bool,
  debt: uint,
  stacker-name: (string-ascii 256),
  created-at-block-height: uint,
  updated-at-block-height: uint,
  stability-fee-accrued: uint,
  stability-fee-last-accrued: uint, ;; indicates the block height at which the stability fee was last accrued (calculated)
  is-liquidated: bool,
  auction-ended: bool,
  leftover-collateral: uint
})
(define-map vault-entries { user: principal } { ids: (list 20 uint) })
(define-map closing-vault
  { user: principal }
  { vault-id: uint }
)
(define-map stacking-payout
  { vault-id: uint, lot-index: uint }
  {
    collateral-amount: uint,
    principal: principal
  }
)
(define-map stacking-payout-lots
  { vault-id: uint }
  {
    ids: (list 500 uint)
  }
)
(define-data-var last-vault-id uint u0)
(define-constant ERR-NOT-AUTHORIZED u7401)

;; ---------------------------------------------------------
;; Getters
;; ---------------------------------------------------------

(define-read-only (get-vault-by-id (id uint))
  (default-to
    {
      id: u0,
      owner: (contract-call? .arkadiko-dao get-dao-owner),
      collateral: u0,
      collateral-type: "",
      collateral-token: "",
      stacked-tokens: u0,
      stacker-name: "",
      revoked-stacking: false,
      debt: u0,
      created-at-block-height: u0,
      updated-at-block-height: u0,
      auto-payoff: false,
      stability-fee-accrued: u0,
      stability-fee-last-accrued: u0,
      is-liquidated: false,
      auction-ended: false,
      leftover-collateral: u0
    }
    (map-get? vaults { id: id })
  )
)

(define-read-only (get-vault-entries (user principal))
  (unwrap! (map-get? vault-entries { user: user }) (tuple (ids (list u0) )))
)

(define-read-only (get-last-vault-id)
  (var-get last-vault-id)
)

(define-read-only (get-stacking-payout (vault-id uint) (lot-index uint))
  (default-to
    { collateral-amount: u0, principal: (contract-call? .arkadiko-dao get-dao-owner) }
    (map-get? stacking-payout { vault-id: vault-id, lot-index: lot-index })
  )
)
(define-read-only (get-stacking-payout-lots (vault-id uint))
  (unwrap! (map-get? stacking-payout-lots { vault-id: vault-id }) (tuple (ids (list u0) )))
)

(define-public (set-last-vault-id (vault-id uint))
  (begin
    (asserts! (is-eq contract-caller (unwrap-panic (contract-call? .arkadiko-dao get-qualified-name-by-name "freddie"))) (err ERR-NOT-AUTHORIZED))

    (ok (var-set last-vault-id vault-id))
  )
)

(define-read-only (get-vaults (user principal))
  (let ((entries (get ids (get-vault-entries user))))
    (ok (map get-vault-by-id entries))
  )
)

(define-public (update-vault (vault-id uint) (data (tuple (id uint) (owner principal) (collateral uint) (collateral-type (string-ascii 12)) (collateral-token (string-ascii 12)) (stacker-name (string-ascii 256)) (stacked-tokens uint) (auto-payoff bool) (revoked-stacking bool) (debt uint) (created-at-block-height uint) (updated-at-block-height uint) (stability-fee-accrued uint) (stability-fee-last-accrued uint) (is-liquidated bool) (auction-ended bool) (leftover-collateral uint))))
  (let ((vault (get-vault-by-id vault-id)))
    (asserts!
      (or
        (is-eq contract-caller (unwrap-panic (contract-call? .arkadiko-dao get-qualified-name-by-name "freddie")))
        (is-eq contract-caller (unwrap-panic (contract-call? .arkadiko-dao get-qualified-name-by-name "stacker-payer")))
        (is-eq contract-caller (unwrap-panic (contract-call? .arkadiko-dao get-qualified-name-by-name "stacker")))
        (is-eq contract-caller (unwrap-panic (contract-call? .arkadiko-dao get-qualified-name-by-name "stacker-2")))
        (is-eq contract-caller (unwrap-panic (contract-call? .arkadiko-dao get-qualified-name-by-name "stacker-3")))
        (is-eq contract-caller (unwrap-panic (contract-call? .arkadiko-dao get-qualified-name-by-name "stacker-4")))
      )
      (err ERR-NOT-AUTHORIZED)
    )
  
    (map-set vaults (tuple (id vault-id)) data)
    (ok true)
  )
)

(define-public (update-vault-entries (user principal) (vault-id uint))
  (let ((entries (get ids (get-vault-entries user))))
    (asserts! (is-eq contract-caller (unwrap-panic (contract-call? .arkadiko-dao get-qualified-name-by-name "freddie"))) (err ERR-NOT-AUTHORIZED))

    (map-set vault-entries { user: user } { ids: (unwrap-panic (as-max-len? (append entries vault-id) u20)) })
    (ok true)
  )
)

(define-private (remove-burned-vault (vault-id uint))
  (let ((current-vault (unwrap-panic (map-get? closing-vault { user: tx-sender }))))
    (if (is-eq vault-id (get vault-id current-vault))
      false
      true
    )
  )
)

(define-public (close-vault (vault-id uint))
  (let (
    (vault (get-vault-by-id vault-id))
    (entries (get ids (get-vault-entries (get owner vault))))
  )
    (asserts! (is-eq contract-caller (unwrap-panic (contract-call? .arkadiko-dao get-qualified-name-by-name "freddie"))) (err ERR-NOT-AUTHORIZED))

    (map-set closing-vault { user: (get owner vault) } { vault-id: vault-id })
    (map-set vault-entries { user: tx-sender } { ids: (filter remove-burned-vault entries) })
    (ok (map-delete vaults { id: vault-id }))
  )
)

(define-public (set-stacker-payout (vault-id uint) (lot-index uint) (collateral-amount uint) (recipient principal))
  (let ((entries (get ids (get-stacking-payout-lots vault-id))))
    (asserts!
      (or
        (is-eq contract-caller (unwrap-panic (contract-call? .arkadiko-dao get-qualified-name-by-name "freddie")))
        (is-eq contract-caller (unwrap-panic (contract-call? .arkadiko-dao get-qualified-name-by-name "auction-engine")))
      )
      (err ERR-NOT-AUTHORIZED)
    )

    (map-set stacking-payout
      { vault-id: vault-id, lot-index: lot-index }
      {
        collateral-amount: collateral-amount,
        principal: recipient
      }
    )
    (if (is-none (index-of entries lot-index))
      (map-set stacking-payout-lots { vault-id: vault-id } { ids: (unwrap-panic (as-max-len? (append entries lot-index) u500)) })
      true
    )
    (ok true)
  )
)

Functions (12)

FunctionAccessArgs
get-vault-by-idread-onlyid: uint
get-vault-entriesread-onlyuser: principal
get-last-vault-idread-only
get-stacking-payoutread-onlyvault-id: uint, lot-index: uint
get-stacking-payout-lotsread-onlyvault-id: uint
set-last-vault-idpublicvault-id: uint
get-vaultsread-onlyuser: principal
update-vaultpublicvault-id: uint, data: (tuple (id uint, owner: principal, collateral: uint, collateral-type: (string-ascii 12
update-vault-entriespublicuser: principal, vault-id: uint
remove-burned-vaultprivatevault-id: uint
close-vaultpublicvault-id: uint
set-stacker-payoutpublicvault-id: uint, lot-index: uint, collateral-amount: uint, recipient: principal