Skip to content
Open
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 news/Clarinet.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ cache_dir = './.cache'
[[project.requirements]]
contract_id = 'STV9K21TBFAK4KNRJXF5DFP8N7W46G4V9RJ5XDY2.sbtc-token'

# Our own mock sBTC, deployed to testnet after the 2026-07-30 reset wiped the
# one above. v6 uses this; v3/v4/v5 still reference the old one.
[[project.requirements]]
contract_id = 'ST2VN1G6EBXPMMAJKCSY1HR50YQCVFSK68KKP9SKW.sbtc-token'

[contracts.news-treasury]
path = 'contracts/news-treasury.clar'
clarity_version = 3
Expand Down
14 changes: 8 additions & 6 deletions news/contracts/news-treasury-v6.clar
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
;; news-treasury-v6

;; sBTC token
;; sBTC token. This is OUR OWN mock (contracts/sbtc-token.clar), deployed to
;; testnet after the 2026-07-30 reset wiped the third-party one we used before.
;; MAINNET DEPLOY: swap this and the literal at every contract-call site below
(define-constant SBTC 'STV9K21TBFAK4KNRJXF5DFP8N7W46G4V9RJ5XDY2.sbtc-token)
;; for 'SM3VDXK3WZZSA84XXFKAFAF15NNZX32CTSG82JFQ4.sbtc-token
(define-constant SBTC 'ST2VN1G6EBXPMMAJKCSY1HR50YQCVFSK68KKP9SKW.sbtc-token)

(define-constant DEPLOYER tx-sender)

Expand Down Expand Up @@ -94,7 +96,7 @@
(begin
(asserts! (is-gov contract-caller) ERR_UNAUTHORIZED)
(asserts! (> amount u0) ERR_ZERO_AMOUNT)
(try! (contract-call? 'STV9K21TBFAK4KNRJXF5DFP8N7W46G4V9RJ5XDY2.sbtc-token transfer amount tx-sender current-contract none))
(try! (contract-call? 'ST2VN1G6EBXPMMAJKCSY1HR50YQCVFSK68KKP9SKW.sbtc-token transfer amount tx-sender current-contract none))
(var-set Balance (+ (var-get Balance) amount))
(var-set WeightedBalance (+ (var-get WeightedBalance) amount))
(print {
Expand All @@ -118,7 +120,7 @@
(asserts! (is-some (var-get Gov)) ERR_NOT_WIRED)
(asserts! (>= amount MIN_SPONSOR) ERR_BELOW_MIN)
(asserts! (> (len name) u0) ERR_EMPTY_NAME)
(try! (contract-call? 'STV9K21TBFAK4KNRJXF5DFP8N7W46G4V9RJ5XDY2.sbtc-token transfer amount tx-sender current-contract none))
(try! (contract-call? 'ST2VN1G6EBXPMMAJKCSY1HR50YQCVFSK68KKP9SKW.sbtc-token transfer amount tx-sender current-contract none))
(var-set Balance (+ (var-get Balance) amount))
(print {
event: "sponsor-in",
Expand Down Expand Up @@ -157,8 +159,8 @@
(var-set Balance (- bal amount))
(var-set WeightedBalance (- weighted (/ (* weighted amount) bal)))

(try! (as-contract? ((with-ft 'STV9K21TBFAK4KNRJXF5DFP8N7W46G4V9RJ5XDY2.sbtc-token "sbtc-token" amount))
(try! (contract-call? 'STV9K21TBFAK4KNRJXF5DFP8N7W46G4V9RJ5XDY2.sbtc-token transfer amount tx-sender recipient none))))
(try! (as-contract? ((with-ft 'ST2VN1G6EBXPMMAJKCSY1HR50YQCVFSK68KKP9SKW.sbtc-token "sbtc-token" amount))
(try! (contract-call? 'ST2VN1G6EBXPMMAJKCSY1HR50YQCVFSK68KKP9SKW.sbtc-token transfer amount tx-sender recipient none))))

(print {
event: "execute-payout",
Expand Down
94 changes: 94 additions & 0 deletions news/contracts/sbtc-token.clar
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
;; sbtc-token
;; Mock sBTC for testnet only. Vendored from the Faktory token that the Stacks
;; testnet reset of 2026-07-30 wiped, so the legion no longer depends on a third
;; party republishing it. NEVER deploy this to mainnet; mainnet uses the real
;; sBTC at SM3VDXK3WZZSA84XXFKAFAF15NNZX32CTSG82JFQ4.sbtc-token.
;;
;; ONE CHANGE from the original: the recipient guard in `transfer` used
;; (as-contract tx-sender), which is unresolved at Clarity 4+ and aborts on
;; publish. Replaced with the `current-contract` keyword, which returns the same
;; principal. Everything else is verbatim.

;; title: Mock sBTC Token
;; version: 1.0
;; summary: Mock implementation of sBTC for local testing
;; description: Implements SIP-010 trait and mimics mainnet sBTC token functionality

;; traits
;;

;; token definitions
(define-fungible-token sbtc-token)

;; constants
(define-constant ERR_NOT_OWNER (err u4))
(define-constant ERR_INVALID_SENDER (err u5))
(define-constant ERR_INVALID_RECIPIENT (err u6))
(define-constant ERR_INSUFFICIENT_BALANCE (err u7))
(define-constant token-decimals u8)
(define-constant INITIAL_SUPPLY u2100000000000000) ;; 21m sBTC with 8 decimals for testing

;; data vars
(define-data-var token-name (string-ascii 32) "sBTC")
(define-data-var token-symbol (string-ascii 10) "sBTC")
(define-data-var token-uri (optional (string-utf8 256)) (some u"https://ipfs.io/ipfs/bafkreibqnozdui4ntgoh3oo437lvhg7qrsccmbzhgumwwjf2smb3eegyqu"))

;; data maps
;;

;; public functions
(define-public (transfer (amount uint) (sender principal) (recipient principal) (memo (optional (buff 34))))
(begin
;; Authorization check
(asserts! (or (is-eq tx-sender sender) (is-eq contract-caller sender)) ERR_NOT_OWNER)
;; Sender validation
(asserts! (not (is-eq sender recipient)) ERR_INVALID_SENDER)
;; Balance check
(asserts! (<= amount (ft-get-balance sbtc-token sender)) ERR_INSUFFICIENT_BALANCE)
;; Recipient validation - ensure not burning tokens
(asserts! (not (is-eq recipient current-contract)) ERR_INVALID_RECIPIENT)
;; Perform transfer
(try! (ft-transfer? sbtc-token amount sender recipient))
;; Handle memo if provided
(match memo to-print (print to-print) 0x)
(ok true)
)
)
;; faucet function for testing
(define-public (faucet)
(begin
(try! (ft-mint? sbtc-token u690000000 tx-sender)) ;; Mint 6.9 sBTC to tx-sender
(ok true)
)

)
;; read only functions
(define-read-only (get-name)
(ok (var-get token-name))
)
(define-read-only (get-symbol)
(ok (var-get token-symbol))

)
(define-read-only (get-decimals)
(ok token-decimals)
)

(define-read-only (get-balance (who principal))
(ok (ft-get-balance sbtc-token who))
)

(define-read-only (get-total-supply)
(ok (ft-get-supply sbtc-token))
)

(define-read-only (get-token-uri)
(ok (var-get token-uri))
)

;; initialize contract
(begin
;; Mint initial supply to contract deployer

(try! (ft-mint? sbtc-token INITIAL_SUPPLY tx-sender))
)
5 changes: 5 additions & 0 deletions news/deployments/default.simnet-plan.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,11 @@ plan:
epoch: '3.0'
- id: 1
transactions:
- transaction-type: emulated-contract-publish
contract-name: sbtc-token
emulated-sender: ST2VN1G6EBXPMMAJKCSY1HR50YQCVFSK68KKP9SKW
path: .cache/requirements/ST2VN1G6EBXPMMAJKCSY1HR50YQCVFSK68KKP9SKW.sbtc-token.clar
clarity-version: 4
- transaction-type: emulated-contract-publish
contract-name: news-treasury-v6
emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM
Expand Down
2 changes: 1 addition & 1 deletion news/tests/news-v6-economics.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const anyone = accounts.get("wallet_5")!;

const TREASURY = "news-treasury-v6";
const GOV = "news-gov-v6";
const SBTC = "STV9K21TBFAK4KNRJXF5DFP8N7W46G4V9RJ5XDY2.sbtc-token";
const SBTC = "ST2VN1G6EBXPMMAJKCSY1HR50YQCVFSK68KKP9SKW.sbtc-token";

const VOTING_DELAY = 2;
const VOTE_WINDOW = 30;
Expand Down
2 changes: 1 addition & 1 deletion news/tests/news-v6.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ const GOV = "news-gov-v6";
const govPrincipal = `${deployer}.${GOV}`;

// The REAL testnet sBTC token, pulled into simnet via [[project.requirements]].
const SBTC = "STV9K21TBFAK4KNRJXF5DFP8N7W46G4V9RJ5XDY2.sbtc-token";
const SBTC = "ST2VN1G6EBXPMMAJKCSY1HR50YQCVFSK68KKP9SKW.sbtc-token";

// Must match news-gov-v6.clar (burn blocks). No VETO_WINDOW in v6.
const VOTING_DELAY = 2;
Expand Down