-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
c58d979
commit a00734c
Showing
16 changed files
with
2,840 additions
and
1 deletion.
There are no files selected for viewing
470 changes: 470 additions & 0 deletions
470
contracts/SP1F12J9QX3BQ32FY5HJNDVN5P309ZM9CE6XBN6YH/pyth-governance-v1.clar
Large diffs are not rendered by default.
Oops, something went wrong.
12 changes: 12 additions & 0 deletions
12
contracts/SP1F12J9QX3BQ32FY5HJNDVN5P309ZM9CE6XBN6YH/pyth-helper-v1.clar
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
|
||
(define-public (verify-and-update-price (pnau-bytes (buff 8192))) | ||
(contract-call? .pyth-oracle-v1 verify-and-update-price-feeds | ||
pnau-bytes | ||
{ | ||
pyth-storage-contract: .pyth-store-v1, | ||
pyth-decoder-contract: .pyth-pnau-decoder-v1, | ||
wormhole-core-contract: .wormhole-core-v1 | ||
})) | ||
|
||
(define-public (read-price (price-feed-id (buff 32))) | ||
(contract-call? .pyth-oracle-v1 read-price-feed price-feed-id .pyth-store-v1)) |
44 changes: 44 additions & 0 deletions
44
contracts/SP1F12J9QX3BQ32FY5HJNDVN5P309ZM9CE6XBN6YH/pyth-oracle-v1.clar
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
;; Title: pyth-oracle | ||
;; Version: v1 | ||
;; Check for latest version: https://github.com/hirosystems/stacks-pyth-bridge#latest-version | ||
;; Report an issue: https://github.com/hirosystems/stacks-pyth-bridge/issues | ||
|
||
(use-trait pyth-storage-trait .pyth-traits-v1.storage-trait) | ||
(use-trait pyth-decoder-trait .pyth-traits-v1.decoder-trait) | ||
(use-trait wormhole-core-trait .wormhole-traits-v1.core-trait) | ||
|
||
;; Generic error | ||
(define-constant ERR_PANIC (err u0)) | ||
;; Balance insufficient for handling fee | ||
(define-constant ERR_BALANCE_INSUFFICIENT (err u402)) | ||
|
||
(define-public (read-price-feed | ||
(price-feed-id (buff 32)) | ||
(pyth-storage-address <pyth-storage-trait>)) | ||
(begin | ||
;; Check execution flow | ||
(try! (contract-call? .pyth-governance-v1 check-storage-contract pyth-storage-address)) | ||
;; Perform contract-call | ||
(contract-call? pyth-storage-address read price-feed-id))) | ||
|
||
(define-public (verify-and-update-price-feeds | ||
(price-feed-bytes (buff 8192)) | ||
(execution-plan { | ||
pyth-storage-contract: <pyth-storage-trait>, | ||
pyth-decoder-contract: <pyth-decoder-trait>, | ||
wormhole-core-contract: <wormhole-core-trait> | ||
})) | ||
(begin | ||
;; Check execution flow | ||
(try! (contract-call? .pyth-governance-v1 check-execution-flow contract-caller (some execution-plan))) | ||
;; Perform contract-call | ||
(let ((pyth-decoder-contract (get pyth-decoder-contract execution-plan)) | ||
(wormhole-core-contract (get wormhole-core-contract execution-plan)) | ||
(pyth-storage-contract (get pyth-storage-contract execution-plan)) | ||
(decoded-prices (try! (contract-call? pyth-decoder-contract decode-and-verify-price-feeds price-feed-bytes wormhole-core-contract))) | ||
(updated-prices (try! (contract-call? pyth-storage-contract write decoded-prices))) | ||
(fee-info (contract-call? .pyth-governance-v1 get-fee-info)) | ||
(fee-amount (* (len updated-prices) (* (get mantissa fee-info) (pow u10 (get exponent fee-info)))))) | ||
;; Charge fee | ||
(unwrap! (stx-transfer? fee-amount tx-sender (get address fee-info)) ERR_BALANCE_INSUFFICIENT) | ||
(ok updated-prices)))) |
328 changes: 328 additions & 0 deletions
328
contracts/SP1F12J9QX3BQ32FY5HJNDVN5P309ZM9CE6XBN6YH/pyth-pnau-decoder-v1.clar
Large diffs are not rendered by default.
Oops, something went wrong.
106 changes: 106 additions & 0 deletions
106
contracts/SP1F12J9QX3BQ32FY5HJNDVN5P309ZM9CE6XBN6YH/pyth-store-v1.clar
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
;; Title: pyth-store | ||
;; Version: v1 | ||
;; Check for latest version: https://github.com/hirosystems/stacks-pyth-bridge#latest-version | ||
;; Report an issue: https://github.com/hirosystems/stacks-pyth-bridge/issues | ||
|
||
(impl-trait .pyth-traits-v1.storage-trait) | ||
|
||
(define-constant ERR_NEWER_PRICE_AVAILABLE (err u5000)) | ||
(define-constant ERR_STALE_PRICE (err u5001)) | ||
(define-constant ERR_INVALID_UPDATES (err u5003)) | ||
|
||
(define-map prices (buff 32) { | ||
price: int, | ||
conf: uint, | ||
expo: int, | ||
ema-price: int, | ||
ema-conf: uint, | ||
publish-time: uint, | ||
prev-publish-time: uint, | ||
}) | ||
|
||
(define-map timestamps (buff 32) uint) | ||
|
||
(define-public (read (price-identifier (buff 32))) | ||
(let ((entry (unwrap! (map-get? prices price-identifier) (err u404)))) | ||
(ok entry))) | ||
|
||
(define-public (write (batch-updates (list 64 { | ||
price-identifier: (buff 32), | ||
price: int, | ||
conf: uint, | ||
expo: int, | ||
ema-price: int, | ||
ema-conf: uint, | ||
publish-time: uint, | ||
prev-publish-time: uint, | ||
}))) | ||
(let ((successful-updates (map unwrapped-entry (filter only-ok-entry (map write-batch-entry batch-updates))))) | ||
;; Ensure that updates are always coming from the right contract | ||
(try! (contract-call? .pyth-governance-v1 check-execution-flow contract-caller none)) | ||
;; Ensure we have at least one entry | ||
(asserts! (> (len successful-updates) u0) ERR_INVALID_UPDATES) | ||
(ok successful-updates))) | ||
|
||
(define-private (write-batch-entry (entry { | ||
price-identifier: (buff 32), | ||
price: int, | ||
conf: uint, | ||
expo: int, | ||
ema-price: int, | ||
ema-conf: uint, | ||
publish-time: uint, | ||
prev-publish-time: uint, | ||
})) | ||
(let ((stale-price-threshold (contract-call? .pyth-governance-v1 get-stale-price-threshold)) | ||
(latest-bitcoin-timestamp (unwrap! (get-block-info? time (- block-height u1)) ERR_STALE_PRICE))) | ||
;; Ensure that we have not processed a newer price | ||
(asserts! (is-price-update-more-recent (get price-identifier entry) (get publish-time entry)) ERR_NEWER_PRICE_AVAILABLE) | ||
;; Ensure that price is not stale | ||
(asserts! (>= (get publish-time entry) (- latest-bitcoin-timestamp stale-price-threshold)) ERR_STALE_PRICE) | ||
;; Update storage | ||
(map-set prices | ||
(get price-identifier entry) | ||
{ | ||
price: (get price entry), | ||
conf: (get conf entry), | ||
expo: (get expo entry), | ||
ema-price: (get ema-price entry), | ||
ema-conf: (get ema-conf entry), | ||
publish-time: (get publish-time entry), | ||
prev-publish-time: (get prev-publish-time entry) | ||
}) | ||
;; Emit event | ||
(print { | ||
type: "price-feed", | ||
action: "updated", | ||
data: entry | ||
}) | ||
;; Update timestamps tracking | ||
(map-set timestamps (get price-identifier entry) (get publish-time entry)) | ||
(ok entry))) | ||
|
||
(define-private (only-ok-entry (entry (response { | ||
price-identifier: (buff 32), | ||
price: int, | ||
conf: uint, | ||
expo: int, | ||
ema-price: int, | ||
ema-conf: uint, | ||
publish-time: uint, | ||
prev-publish-time: uint, | ||
} uint))) (is-ok entry)) | ||
|
||
(define-private (unwrapped-entry (entry (response { | ||
price-identifier: (buff 32), | ||
price: int, | ||
conf: uint, | ||
expo: int, | ||
ema-price: int, | ||
ema-conf: uint, | ||
publish-time: uint, | ||
prev-publish-time: uint, | ||
} uint))) (unwrap-panic entry)) | ||
|
||
(define-private (is-price-update-more-recent (price-identifier (buff 32)) (publish-time uint)) | ||
(> publish-time (default-to u0 (map-get? timestamps price-identifier)))) |
80 changes: 80 additions & 0 deletions
80
contracts/SP1F12J9QX3BQ32FY5HJNDVN5P309ZM9CE6XBN6YH/pyth-traits-v1.clar
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
;; Title: pyth-traits | ||
;; Version: v1 | ||
;; Check for latest version: https://github.com/hirosystems/stacks-pyth-bridge#latest-version | ||
;; Report an issue: https://github.com/hirosystems/stacks-pyth-bridge/issues | ||
|
||
(use-trait wormhole-core-trait .wormhole-traits-v1.core-trait) | ||
|
||
(define-trait decoder-trait | ||
( | ||
(decode-and-verify-price-feeds ((buff 8192) <wormhole-core-trait>) (response (list 64 { | ||
price-identifier: (buff 32), | ||
price: int, | ||
conf: uint, | ||
expo: int, | ||
ema-price: int, | ||
ema-conf: uint, | ||
publish-time: uint, | ||
prev-publish-time: uint, | ||
}) uint)) | ||
) | ||
) | ||
|
||
(define-trait storage-trait | ||
( | ||
(read ((buff 32)) (response { | ||
price: int, | ||
conf: uint, | ||
expo: int, | ||
ema-price: int, | ||
ema-conf: uint, | ||
publish-time: uint, | ||
prev-publish-time: uint, | ||
} uint)) | ||
|
||
(write ((list 64 { | ||
price-identifier: (buff 32), | ||
price: int, | ||
conf: uint, | ||
expo: int, | ||
ema-price: int, | ||
ema-conf: uint, | ||
publish-time: uint, | ||
prev-publish-time: uint, | ||
})) (response (list 64 { | ||
price-identifier: (buff 32), | ||
price: int, | ||
conf: uint, | ||
expo: int, | ||
ema-price: int, | ||
ema-conf: uint, | ||
publish-time: uint, | ||
prev-publish-time: uint, | ||
}) uint)) | ||
) | ||
) | ||
|
||
(define-trait proxy-trait | ||
( | ||
(read-price-feed ((buff 32)) (response { | ||
price: int, | ||
conf: uint, | ||
expo: int, | ||
ema-price: int, | ||
ema-conf: uint, | ||
publish-time: uint, | ||
prev-publish-time: uint, | ||
} uint)) | ||
|
||
(verify-and-update-price-feeds ((buff 8192) <wormhole-core-trait>) (response (list 64 { | ||
price-identifier: (buff 32), | ||
price: int, | ||
conf: uint, | ||
expo: int, | ||
ema-price: int, | ||
ema-conf: uint, | ||
publish-time: uint, | ||
prev-publish-time: uint, | ||
}) uint)) | ||
) | ||
) |
Oops, something went wrong.