Source Code

;; Oracle Trait 
(impl-trait .oracle-trait-vpv-5.oracle-trait)

(use-trait registry-trait .registry-trait-vpv-5.registry-trait)

(define-constant ERR_NO_ORACLE_PRICE (err u700))
(define-constant ERR_STALE_ORACLE_PRICE (err u701))
(define-constant ERR_INVALID_SOURCE (err u702))

(define-constant SOURCE_ARKADIKO u1)
(define-constant SOURCE_DIA u2)

(define-constant SBTC_TOKEN_KEY_ARKADIKO "BTC")
(define-constant SBTC_TOKEN_KEY_DIA "BTC/USD")

(define-data-var current-source uint SOURCE_ARKADIKO)

;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; oracle-trait BEGIN
;;;;;;;;;;;;;;;;;;;;;;;;;;;

(define-public (set-source (source uint))
    (begin 
        (try! (contract-call? .controller-vpv-5 is-admin tx-sender))
        (asserts! (or (is-eq source SOURCE_ARKADIKO) (is-eq source SOURCE_DIA)) ERR_INVALID_SOURCE)
        (var-set current-source source)
        (ok true)
    )
)

(define-public (get-price (registry <registry-trait>))
    (let 
        (
            (source (var-get current-source))
            (oracle-token-key (if (is-eq source SOURCE_ARKADIKO) SBTC_TOKEN_KEY_ARKADIKO SBTC_TOKEN_KEY_DIA))
            (current-burn-block-height burn-block-height)
            (current-stacks-block-timestamp (get-stacks-block-info? time (- stacks-block-height u1)))
        )
        ;; verify source is correct
         (asserts! (or (is-eq source SOURCE_ARKADIKO) (is-eq source SOURCE_DIA)) ERR_INVALID_SOURCE)

       (if (is-eq source SOURCE_ARKADIKO)
            (get-arkadiko-price oracle-token-key current-burn-block-height registry)
            (get-dia-price oracle-token-key (unwrap-panic current-stacks-block-timestamp) registry)
       )
    )
)

;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; oracle-trait END
;;;;;;;;;;;;;;;;;;;;;;;;;;;

(define-read-only (get-source)
    (ok (var-get current-source))
)

(define-private (get-arkadiko-price (token-key (string-ascii 12)) (current-burn-block uint) (registry <registry-trait>))
    (let 
        (
            (token (unwrap! (contract-call? .oracle-arkadiko-mock fetch-price token-key) ERR_NO_ORACLE_PRICE))
            (token-price (get last-price token))
            (token-block (get last-block token))
            (oracle-stale-threshold (try! (contract-call? registry get-oracle-stale-threshold)))
        ) 
        (asserts! (>= (+ token-block oracle-stale-threshold) current-burn-block) ERR_STALE_ORACLE_PRICE)
        (ok token-price)
    )
)

(define-private (get-dia-price (token-key (string-ascii 12)) (current-timestamp uint) (registry <registry-trait>))
    (let 
        (
            ;; Testnet
            ;; (token (unwrap-panic (contract-call? 'ST1S5ZGRZV5K4S9205RWPRTX9RGS9JV40KQMR4G1J.dia-oracle get-value token-key)))
            (token (unwrap-panic (contract-call? .oracle-dia-mock get-value token-key)))
            (token-price (get value token))
            (token-timestamp (get timestamp token))
            (oracle-stale-threshold (try! (contract-call? registry get-oracle-stale-threshold)))
            (oracle-stale-threshold-seconds (* oracle-stale-threshold u10 u60)) ;; blocks * 10 min/block * 60 sec
        ) 
        (asserts! (>= (+ token-timestamp oracle-stale-threshold-seconds) current-timestamp) ERR_STALE_ORACLE_PRICE)
        (ok token-price)
    )
)

Functions (5)

FunctionAccessArgs
set-sourcepublicsource: uint
get-pricepublicregistry: <registry-trait>
get-sourceread-only
get-arkadiko-priceprivatetoken-key: (string-ascii 12
get-dia-priceprivatetoken-key: (string-ascii 12