diff --git a/contracts/pyth-governance-v2.clar b/contracts/pyth-governance-v2.clar index de20e31..ee6e76f 100644 --- a/contracts/pyth-governance-v2.clar +++ b/contracts/pyth-governance-v2.clar @@ -26,7 +26,7 @@ ;; Special Stacks operation: update recipient address (define-constant PTGM_UPDATE_RECIPIENT_ADDRESS 0xa0) ;; Special Stacks operation: update storage contract address -(define-constant PTGM_UPDATE_PYTH_STORE_ADDRESS 0xa1) +(define-constant PTGM_UPDATE_PYTH_STORAGE_ADDRESS 0xa1) ;; Special Stacks operation: update decoder contract address (define-constant PTGM_UPDATE_PYTH_DECODER_ADDRESS 0xa2) ;; Stacks chain id attributed by Pyth @@ -237,7 +237,7 @@ (vaa (try! (contract-call? wormhole-core-contract parse-and-verify-vaa vaa-bytes))) (ptgm (try! (parse-and-verify-ptgm (get payload vaa) (get sequence vaa))))) ;; Ensure action's expected - (asserts! (is-eq (get action ptgm) PTGM_UPDATE_PYTH_STORE_ADDRESS) ERR_UNEXPECTED_ACTION) + (asserts! (is-eq (get action ptgm) PTGM_UPDATE_PYTH_STORAGE_ADDRESS) ERR_UNEXPECTED_ACTION) ;; Ensure that the action is authorized (try! (check-update-source (get emitter-chain vaa) (get emitter-address vaa))) ;; Ensure that the latest wormhole contract is used diff --git a/contracts/pyth-storage-v3.clar b/contracts/pyth-storage-v3.clar index 9e397b1..09e4b60 100644 --- a/contracts/pyth-storage-v3.clar +++ b/contracts/pyth-storage-v3.clar @@ -53,9 +53,9 @@ (let ( (entry (unwrap! (map-get? prices price-identifier) ERR_PRICE_FEED_NOT_FOUND)) (stale-price-threshold (contract-call? .pyth-governance-v2 get-stale-price-threshold)) - (latest-bitcoin-timestamp (unwrap! (get-stacks-block-info? time (- stacks-block-height u1)) ERR_STALE_PRICE)) + (latest-stacks-timestamp (unwrap! (get-stacks-block-info? time (- stacks-block-height u1)) ERR_STALE_PRICE)) ) - (asserts! (>= (get publish-time entry) (+ (- latest-bitcoin-timestamp stale-price-threshold) STACKS_BLOCK_TIME)) ERR_STALE_PRICE) + (asserts! (>= (get publish-time entry) (+ (- latest-stacks-timestamp stale-price-threshold) STACKS_BLOCK_TIME)) ERR_STALE_PRICE) (ok entry))) (define-public (write (batch-updates (list 64 { diff --git a/contracts/wormhole/wormhole-core-v3.clar b/contracts/wormhole/wormhole-core-v3.clar index ab79047..8f79649 100644 --- a/contracts/wormhole/wormhole-core-v3.clar +++ b/contracts/wormhole/wormhole-core-v3.clar @@ -69,9 +69,11 @@ ;; Overlay present in vaa bytes (define-constant ERR_GSU_CHECK_OVERLAY (err u1307)) ;; Empty guardian set -(define-constant ERR_EMPTY_GUARIDIAN_SET (err u1308)) +(define-constant ERR_EMPTY_GUARDIAN_SET (err u1308)) ;; Guardian Set Update emission payload unauthorized (define-constant ERR_DUPLICATED_GUARDIAN_ADDRESSES (err u1309)) +;; Unable to get stacks timestamp +(define-constant ERR_STACKS_TIMESTAMP (err u1310)) ;; Guardian set upgrade emitting address (define-constant GSU-EMITTING-ADDRESS 0x0000000000000000000000000000000000000000000000000000000000000004) @@ -87,7 +89,8 @@ (define-constant CORE_CHAIN_ID u0) ;; Guardian eth address size (define-constant GUARDIAN_ETH_ADDRESS_SIZE u20) - +;; 24 hours in seconds +(define-constant TWENTY_FOUR_HOURS u86400) ;;;; Data vars ;; Guardian Set Update uncompressed public keys invalid @@ -96,6 +99,8 @@ (define-constant deployer contract-caller) ;; Keep track of the active guardian set-id (define-data-var active-guardian-set-id uint u0) +;; Keep track of exiting guardian set +(define-data-var previous-guardian-set {set-id: uint, expires-at: uint} {set-id: u0, expires-at: u0}) ;;;; Data maps @@ -180,11 +185,13 @@ ;; @desc Parse and check the validity of a Verified Action Approval (VAA) ;; @param vaa-bytes: (define-read-only (parse-and-verify-vaa (vaa-bytes (buff 8192))) - (let ((message (try! (parse-vaa vaa-bytes)))) - ;; Ensure that the guardian-set-id is the active one - (asserts! (is-eq (get guardian-set-id (get vaa message)) (var-get active-guardian-set-id)) - ERR_VAA_CHECKS_GUARDIAN_SET_CONSISTENCY) - (let ((active-guardians (unwrap! (map-get? guardian-sets (get guardian-set-id (get vaa message))) ERR_VAA_CHECKS_GUARDIAN_SET_CONSISTENCY)) + (let ( + (message (try! (parse-vaa vaa-bytes))) + (guardian-set-id (get guardian-set-id (get vaa message))) + ) + ;; Ensure that the guardian-set-id is the active one or unexpired previous one + (asserts! (try! (is-valid-guardian-set guardian-set-id)) ERR_VAA_CHECKS_GUARDIAN_SET_CONSISTENCY) + (let ((active-guardians (unwrap! (map-get? guardian-sets guardian-set-id) ERR_VAA_CHECKS_GUARDIAN_SET_CONSISTENCY)) (signatures-from-active-guardians (fold batch-check-active-public-keys (get recovered-public-keys message) { active-guardians: active-guardians, @@ -228,10 +235,10 @@ ;; Check emitting address (asserts! (is-eq (get emitter-chain vaa) GSU-EMITTING-CHAIN) ERR_GSU_CHECK_EMITTER) ;; ensure guardian set has atleast one member - (asserts! (>= (len result) u1) ERR_EMPTY_GUARIDIAN_SET) + (asserts! (>= (len result) u1) ERR_EMPTY_GUARDIAN_SET) ;; Update storage (map-set guardian-sets set-id result) - (var-set active-guardian-set-id set-id) + (try! (set-new-guardian-set-id set-id)) (var-set guardian-set-initialized true) ;; Emit Event (print { @@ -415,3 +422,32 @@ ) ) ) + +(define-private (set-new-guardian-set-id (new-set-id uint)) + (if (var-get guardian-set-initialized) + (let ( + (latest-stacks-timestamp (unwrap! (get-stacks-block-info? time (- stacks-block-height u1)) ERR_STACKS_TIMESTAMP)) + (previous-set-expires-at (+ TWENTY_FOUR_HOURS latest-stacks-timestamp)) + ) + (var-set previous-guardian-set { + set-id: (var-get active-guardian-set-id), + expires-at: previous-set-expires-at + }) + (var-set active-guardian-set-id new-set-id) + (ok true) + ) + (begin (var-set active-guardian-set-id new-set-id) (ok true)) + ) +) + +(define-private (is-valid-guardian-set (set-id uint)) + (if (is-eq (var-get active-guardian-set-id) set-id) + (ok true) + (let ( + (prev-guardian-set (var-get previous-guardian-set)) + (prev-guardian-set-id (get set-id prev-guardian-set)) + (prev-guardian-set-expires-at (get expires-at prev-guardian-set)) + (latest-stacks-timestamp (unwrap! (get-stacks-block-info? time (- stacks-block-height u1)) ERR_STACKS_TIMESTAMP)) + ) (ok (and (is-eq prev-guardian-set-id set-id) (>= prev-guardian-set-expires-at latest-stacks-timestamp)))) + ) +)