Source Code

;; Peg Ratio Tracker Contract
;; Monitors sBTC/BTC peg ratio and detects de-pegging events
;; Alerts when ratio deviates beyond acceptable thresholds

(define-constant contract-owner tx-sender)
(define-constant err-owner-only (err u500))
(define-constant err-not-authorized (err u501))
(define-constant err-invalid-ratio (err u502))
(define-constant err-not-found (err u503))

;; Perfect peg = 1,000,000 (1.0 with 6 decimal precision)
(define-constant PERFECT-PEG u1000000)
;; Alert if deviation > 1% (10000 basis points = 1%)
(define-constant DEPEG-THRESHOLD-BPS u100)

(define-data-var current-ratio uint PERFECT-PEG)
(define-data-var last-update uint u0)
(define-data-var depeg-count uint u0)
(define-data-var snapshot-count uint u0)
(define-data-var tracker-active bool true)

(define-map authorized-updaters principal bool)

;; Ratio snapshots
(define-map ratio-snapshots uint
  {
    ratio: uint,
    sbtc-supply: uint,
    btc-reserve: uint,
    deviation-bps: uint,
    block-height: uint,
    updater: principal,
    is-depegged: bool
  }
)

;; Depeg events
(define-map depeg-events uint
  {
    ratio-at-depeg: uint,
    deviation-bps: uint,
    block-height: uint,
    resolved: bool,
    resolved-at: (optional uint),
    max-deviation: uint
  }
)

;; Read-only
(define-read-only (get-current-ratio)
  (var-get current-ratio)
)

(define-read-only (get-snapshot (snapshot-id uint))
  (map-get? ratio-snapshots snapshot-id)
)

(define-read-only (get-depeg-event (event-id uint))
  (map-get? depeg-events event-id)
)

(define-read-only (calculate-deviation-bps (ratio uint))
  (if (>= ratio PERFECT-PEG)
    (/ (* (- ratio PERFECT-PEG) u10000) PERFECT-PEG)
    (/ (* (- PERFECT-PEG ratio) u10000) PERFECT-PEG)
  )
)

(define-read-only (is-depegged (ratio uint))
  (> (calculate-deviation-bps ratio) DEPEG-THRESHOLD-BPS)
)

(define-read-only (get-peg-health)
  {
    ratio: (var-get current-ratio),
    deviation-bps: (calculate-deviation-bps (var-get current-ratio)),
    is-depegged: (is-depegged (var-get current-ratio)),
    depeg-events: (var-get depeg-count),
    last-update: (var-get last-update)
  }
)

;; Public functions
(define-public (add-updater (updater principal))
  (begin
    (asserts! (is-eq tx-sender contract-owner) err-owner-only)
    (map-set authorized-updaters updater true)
    (ok updater)
  )
)

(define-public (update-ratio (new-ratio uint) (sbtc-supply uint) (btc-reserve uint))
  (let (
    (snapshot-id (var-get snapshot-count))
    (deviation (calculate-deviation-bps new-ratio))
    (depegged (> deviation DEPEG-THRESHOLD-BPS))
  )
    (asserts! (default-to false (map-get? authorized-updaters tx-sender)) err-not-authorized)
    (asserts! (> new-ratio u0) err-invalid-ratio)

    (map-set ratio-snapshots snapshot-id {
      ratio: new-ratio,
      sbtc-supply: sbtc-supply,
      btc-reserve: btc-reserve,
      deviation-bps: deviation,
      block-height: stacks-block-height,
      updater: tx-sender,
      is-depegged: depegged
    })

    (var-set current-ratio new-ratio)
    (var-set last-update stacks-block-height)
    (var-set snapshot-count (+ snapshot-id u1))

    ;; Record depeg event if threshold exceeded
    (if depegged
      (let ((event-id (var-get depeg-count)))
        (map-set depeg-events event-id {
          ratio-at-depeg: new-ratio,
          deviation-bps: deviation,
          block-height: stacks-block-height,
          resolved: false,
          resolved-at: none,
          max-deviation: deviation
        })
        (var-set depeg-count (+ event-id u1))
        (ok { ratio: new-ratio, deviation-bps: deviation, depeg-detected: true, event-id: event-id })
      )
      (ok { ratio: new-ratio, deviation-bps: deviation, depeg-detected: false, event-id: u0 })
    )
  )
)

(define-public (resolve-depeg-event (event-id uint))
  (match (map-get? depeg-events event-id)
    event
    (begin
      (asserts! (default-to false (map-get? authorized-updaters tx-sender)) err-not-authorized)
      (map-set depeg-events event-id (merge event {
        resolved: true,
        resolved-at: (some stacks-block-height)
      }))
      (ok { event-id: event-id, resolved: true })
    )
    err-not-found
  )
)

Functions (9)

FunctionAccessArgs
get-current-ratioread-only
get-snapshotread-onlysnapshot-id: uint
get-depeg-eventread-onlyevent-id: uint
calculate-deviation-bpsread-onlyratio: uint
is-depeggedread-onlyratio: uint
get-peg-healthread-only
add-updaterpublicupdater: principal
update-ratiopublicnew-ratio: uint, sbtc-supply: uint, btc-reserve: uint
resolve-depeg-eventpublicevent-id: uint