Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Modular Clarity Update #1008

Merged
merged 22 commits into from
Dec 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions contracts/Clarinet.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ path = 'contracts/sbtc-deposit.clar'
clarity_version = 3
epoch = 3.0

[contracts.sbtc-deposit-update-test]
path = 'contracts/sbtc-deposit-update-test.clar'
setzeus marked this conversation as resolved.
Show resolved Hide resolved
clarity_version = 3
epoch = 3.0

[contracts.sbtc-registry]
path = 'contracts/sbtc-registry.clar'
clarity_version = 3
Expand Down
37 changes: 18 additions & 19 deletions contracts/contracts/sbtc-bootstrap-signers.clar
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
;; sBTC Bootstrap Signers contract

;; constants

;; The required length of public keys
(define-constant key-size u33)

;; errors

;; if err is u200, it's the agg key
;; if err is u210>, it's the key at index (err - 210)
(define-constant ERR_KEY_SIZE_PREFIX (unwrap-err! ERR_KEY_SIZE (err true)))
Expand All @@ -17,14 +14,6 @@
;; equal to 100% of the total number of signer keys.
(define-constant ERR_SIGNATURE_THRESHOLD (err u202))

;; data vars
;;

;; data maps
;;

;; public functions

;; Rotate keys
;; Used to rotate the keys of the signers. This is called whenever
;; the signer set is updated.
Expand All @@ -35,15 +24,18 @@
)
(let
(
(current-signer-data (contract-call? .sbtc-registry get-current-signer-data))
(new-signer-principal (pubkeys-to-principal new-keys new-signature-threshold))
)

;; Check that more than 1 key is in the new set
(asserts! (> (len new-keys) u1) ERR_KEY_SIZE)

;; Check that the signature threshold is valid
(asserts! (and (> new-signature-threshold (/ (len new-keys) u2))
(<= new-signature-threshold (len new-keys))) ERR_SIGNATURE_THRESHOLD)

;; Check that the caller is the current signer principal
(asserts! (is-eq (get current-signer-principal current-signer-data) tx-sender) ERR_INVALID_CALLER)
;; Check that the tx-sender is the current signer principal
(asserts! (is-eq (contract-call? .sbtc-registry get-current-signer-principal) tx-sender) ERR_INVALID_CALLER)

;; Checks that length of each key is exactly 33 bytes
(try! (fold signer-key-length-check new-keys (ok u0)))
Expand All @@ -52,13 +44,22 @@
(asserts! (is-eq (len new-aggregate-pubkey) key-size) ERR_KEY_SIZE)

;; Call into .sbtc-registry to update the keys & address
(ok (try! (contract-call? .sbtc-registry rotate-keys new-keys new-signer-principal new-aggregate-pubkey new-signature-threshold)))
(contract-call? .sbtc-registry rotate-keys new-keys new-signer-principal new-aggregate-pubkey new-signature-threshold)
)
)

;; read only functions
;; Update protocol contract
;; Used to update one of the three protocol contracts
(define-public (update-protocol-contract-wrapper (contract-type (buff 1)) (contract-address principal))
(begin
;; Check that the tx-sender is the current signer principal
(asserts! (is-eq (contract-call? .sbtc-registry get-current-signer-principal) tx-sender) ERR_INVALID_CALLER)
;; Call into .sbtc-registry to update the protocol contract
(contract-call? .sbtc-registry update-protocol-contract contract-type contract-address)
)
)

;; private functions
;; read only functions

;; Signer Key Length Check
;; Checks that the length of each key is exactly 33 bytes
Expand Down Expand Up @@ -125,8 +126,6 @@
)
)



(define-read-only (bytes-len (bytes (buff 33)))
(unwrap-panic (element-at BUFF_TO_BYTE (len bytes)))
)
Expand Down
107 changes: 107 additions & 0 deletions contracts/contracts/sbtc-deposit-update-test.clar
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
;; sBTC Deposit v1 contract (updated)

;; constants

;; The required length of a txid
(define-constant txid-length u32)
(define-constant dust-limit u546)

;; protocol contract type
(define-constant deposit-role 0x01)

;; error codes
;; TXID used in deposit is not the correct length
(define-constant ERR_TXID_LEN (err u300))
;; Deposit has already been completed
(define-constant ERR_DEPOSIT_REPLAY (err u301))
(define-constant ERR_LOWER_THAN_DUST (err u302))
(define-constant ERR_DEPOSIT_INDEX_PREFIX (unwrap-err! ERR_DEPOSIT (err true)))
(define-constant ERR_DEPOSIT (err u303))
(define-constant ERR_INVALID_CALLER (err u304))
(define-constant ERR_INVALID_BURN_HASH (err u305))

;; public functions

;; Accept a new deposit request
;; Note that this function can only be called by the current
;; bootstrap signer set address - it cannot be called by users directly.
;; This function handles the validation & minting of sBTC, it then calls
;; into the sbtc-registry contract to update the state of the protocol
(define-public (complete-deposit-wrapper (txid (buff 32))
(vout-index uint)
(amount uint)
(recipient principal)
(burn-hash (buff 32))
(burn-height uint)
(sweep-txid (buff 32)))
(let
(
(current-signer-data (contract-call? .sbtc-registry get-current-signer-data))
(replay-fetch (contract-call? .sbtc-registry get-deposit-status txid vout-index))
)

;; Check that the caller is the current signer principal
(asserts! (is-eq (get current-signer-principal current-signer-data) tx-sender) ERR_INVALID_CALLER)

;; Check that amount is greater than dust limit
(asserts! (>= amount dust-limit) ERR_LOWER_THAN_DUST)

;; Check that txid is the correct length
(asserts! (is-eq (len txid) txid-length) ERR_TXID_LEN)

;; Check that sweep txid is the correct length
(asserts! (is-eq (len sweep-txid) txid-length) ERR_TXID_LEN)

;; Assert that the deposit has not already been completed (no replay)
(asserts! (is-none replay-fetch) ERR_DEPOSIT_REPLAY)

;; Verify that Bitcoin hasn't forked by comparing the burn hash provided
(asserts! (is-eq (some burn-hash) (get-burn-header burn-height)) ERR_INVALID_BURN_HASH)

;; Mint the sBTC to the recipient
(try! (contract-call? .sbtc-token protocol-mint amount recipient deposit-role))

;; Complete the deposit
(contract-call? .sbtc-registry complete-deposit txid vout-index amount recipient burn-hash burn-height sweep-txid)
)
)

;; Return the bitcoin header hash of the bitcoin block at the given height.
(define-read-only (get-burn-header (height uint))
(get-burn-block-info? header-hash height)
)

;; Accept multiple new deposit requests
;; Note that this function can only be called by the current
;; bootstrap signer set address - it cannot be called by users directly.
;;
;; This function handles the validation & minting of sBTC by handling multiple (up to 1000) deposits at a time,
;; it then calls into the sbtc-registry contract to update the state of the protocol.
(define-public (complete-deposits-wrapper
(deposits (list 650 {txid: (buff 32), vout-index: uint, amount: uint, recipient: principal, burn-hash: (buff 32), burn-height: uint, sweep-txid: (buff 32)}))
)
(begin
;; Check that the caller is the current signer principal
(asserts! (is-eq
(contract-call? .sbtc-registry get-current-signer-principal)
tx-sender
) ERR_INVALID_CALLER)

(fold complete-individual-deposits-helper deposits (ok u0))
)
)

;; private functions
;; #[allow(unchecked_data)]
(define-private (complete-individual-deposits-helper (deposit {txid: (buff 32), vout-index: uint, amount: uint, recipient: principal, burn-hash: (buff 32), burn-height: uint, sweep-txid: (buff 32)}) (helper-response (response uint uint)))
(match helper-response
index
(begin
(unwrap! (complete-deposit-wrapper (get txid deposit) (get vout-index deposit) (get amount deposit) (get recipient deposit) (get burn-hash deposit) (get burn-height deposit) (get sweep-txid deposit)) (err (+ ERR_DEPOSIT_INDEX_PREFIX (+ u10 index))))
(ok (+ index u1))
)
err-response
(err err-response)
)
)

9 changes: 4 additions & 5 deletions contracts/contracts/sbtc-deposit.clar
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
(define-constant txid-length u32)
(define-constant dust-limit u546)

;; protocol contract type
(define-constant deposit-role 0x01)

;; error codes
;; TXID used in deposit is not the correct length
(define-constant ERR_TXID_LEN (err u300))
Expand All @@ -17,10 +20,6 @@
(define-constant ERR_INVALID_CALLER (err u304))
(define-constant ERR_INVALID_BURN_HASH (err u305))

;; data vars

;; data maps

;; public functions

;; Accept a new deposit request
Expand Down Expand Up @@ -60,7 +59,7 @@
(asserts! (is-eq (some burn-hash) (get-burn-header burn-height)) ERR_INVALID_BURN_HASH)

;; Mint the sBTC to the recipient
(try! (contract-call? .sbtc-token protocol-mint amount recipient))
(try! (contract-call? .sbtc-token protocol-mint amount recipient deposit-role))

;; Complete the deposit
(contract-call? .sbtc-registry complete-deposit txid vout-index amount recipient burn-hash burn-height sweep-txid)
Expand Down
Loading
Loading