From 38edcec707c7ae392b83a685d9b88de92fac021b Mon Sep 17 00:00:00 2001 From: david-cmd-byte Date: Sun, 9 Mar 2025 09:31:37 +0100 Subject: [PATCH 1/7] feat: Add governance proposals and user account data maps - Define `Proposals` map to store governance proposal details including creator, description, start/end blocks, execution status, votes for/against, and minimum votes. - Define `UserPositions` map to store user account data including total collateral, total debt, health factor, last updated timestamp, stx staked, analytics tokens, voting power, tier level, and rewards multiplier. --- Clarinet.toml | 30 +++++++-------- contracts/analytics-token.clar | 68 ++++++++++++++++++++++++++++++++++ tests/analytics-token.test.ts | 21 +++++++++++ 3 files changed, 103 insertions(+), 16 deletions(-) create mode 100644 contracts/analytics-token.clar create mode 100644 tests/analytics-token.test.ts diff --git a/Clarinet.toml b/Clarinet.toml index f31dacc..3d462c8 100644 --- a/Clarinet.toml +++ b/Clarinet.toml @@ -1,21 +1,19 @@ [project] -name = "analytics-token-staking" -description = "" +name = 'analytics-token-staking' +description = '' authors = [] telemetry = true -cache_dir = "./.cache" - -# [contracts.counter] -# path = "contracts/counter.clar" - +cache_dir = './.cache' +requirements = [] +[contracts.analytics-token] +path = 'contracts/analytics-token.clar' +clarity_version = 3 +epoch = 3.1 [repl.analysis] -passes = ["check_checker"] -check_checker = { trusted_sender = false, trusted_caller = false, callee_filter = false } +passes = ['check_checker'] -# Check-checker settings: -# trusted_sender: if true, inputs are trusted after tx_sender has been checked. -# trusted_caller: if true, inputs are trusted after contract-caller has been checked. -# callee_filter: if true, untrusted data may be passed into a private function without a -# warning, if it gets checked inside. This check will also propagate up to the -# caller. -# More informations: https://www.hiro.so/blog/new-safety-checks-in-clarinet +[repl.analysis.check_checker] +strict = false +trusted_sender = false +trusted_caller = false +callee_filter = false diff --git a/contracts/analytics-token.clar b/contracts/analytics-token.clar new file mode 100644 index 0000000..1eb5ba0 --- /dev/null +++ b/contracts/analytics-token.clar @@ -0,0 +1,68 @@ +;; Title: Analytics Token Staking and Governance Contract + +;; Summary: The Analytics Token Staking and Governance Contract enables users to stake STX tokens to earn ANALYTICS-TOKEN rewards, +;; participate in protocol governance, and access tiered benefits. +;; Key features include dynamic reward multipliers based on stake size/lock duration, +;; a governance system for proposals/voting, cooldown-protected unstaking, and administrative controls for safety. + +;; Description: A Clarity smart contract for staking STX tokens, earning analytics tokens, +;; and participating in protocol governance through a tiered system with voting capabilities. + +;; Token Definition +(define-fungible-token ANALYTICS-TOKEN u0) + +;; Contract Owner & Error Codes +(define-constant CONTRACT-OWNER tx-sender) +(define-constant ERR-NOT-AUTHORIZED (err u1000)) +(define-constant ERR-INVALID-PROTOCOL (err u1001)) +(define-constant ERR-INVALID-AMOUNT (err u1002)) +(define-constant ERR-INSUFFICIENT-STX (err u1003)) +(define-constant ERR-COOLDOWN-ACTIVE (err u1004)) +(define-constant ERR-NO-STAKE (err u1005)) +(define-constant ERR-BELOW-MINIMUM (err u1006)) +(define-constant ERR-PAUSED (err u1007)) + +;; Contract State Variables +(define-data-var contract-paused bool false) +(define-data-var emergency-mode bool false) +(define-data-var stx-pool uint u0) + +;; Staking Parameters +(define-data-var base-reward-rate uint u500) ;; 5% base rate (100 = 1%) +(define-data-var bonus-rate uint u100) ;; 1% bonus for longer staking +(define-data-var minimum-stake uint u1000000) ;; Minimum stake amount +(define-data-var cooldown-period uint u1440) ;; 24 hour cooldown in blocks +(define-data-var proposal-count uint u0) + +;; Data Maps + +;; Governance Proposals +(define-map Proposals + { proposal-id: uint } + { + creator: principal, + description: (string-utf8 256), + start-block: uint, + end-block: uint, + executed: bool, + votes-for: uint, + votes-against: uint, + minimum-votes: uint + } +) + +;; User Account Data +(define-map UserPositions + principal + { + total-collateral: uint, + total-debt: uint, + health-factor: uint, + last-updated: uint, + stx-staked: uint, + analytics-tokens: uint, + voting-power: uint, + tier-level: uint, + rewards-multiplier: uint + } +) \ No newline at end of file diff --git a/tests/analytics-token.test.ts b/tests/analytics-token.test.ts new file mode 100644 index 0000000..4bb9cf3 --- /dev/null +++ b/tests/analytics-token.test.ts @@ -0,0 +1,21 @@ + +import { describe, expect, it } from "vitest"; + +const accounts = simnet.getAccounts(); +const address1 = accounts.get("wallet_1")!; + +/* + The test below is an example. To learn more, read the testing documentation here: + https://docs.hiro.so/stacks/clarinet-js-sdk +*/ + +describe("example tests", () => { + it("ensures simnet is well initalised", () => { + expect(simnet.blockHeight).toBeDefined(); + }); + + // it("shows an example", () => { + // const { result } = simnet.callReadOnlyFn("counter", "get-counter", [], address1); + // expect(result).toBeUint(0); + // }); +}); From d187c79fcd72c1e96d8f0d90b6806690a0f16d23 Mon Sep 17 00:00:00 2001 From: david-cmd-byte Date: Sun, 9 Mar 2025 09:32:28 +0100 Subject: [PATCH 2/7] feat: Add staking positions and tier system configuration - Define `StakingPositions` map to store staking details including amount, start block, last claim, lock period, cooldown start, and accumulated rewards. - Define `TierLevels` map to configure tier levels with minimum stake, reward multiplier, and enabled features. - Implement `initialize-contract` public function to set up initial tier levels with respective configurations. --- contracts/analytics-token.clar | 53 ++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/contracts/analytics-token.clar b/contracts/analytics-token.clar index 1eb5ba0..4bd0a70 100644 --- a/contracts/analytics-token.clar +++ b/contracts/analytics-token.clar @@ -65,4 +65,57 @@ tier-level: uint, rewards-multiplier: uint } +) + +;; Staking Positions +(define-map StakingPositions + principal + { + amount: uint, + start-block: uint, + last-claim: uint, + lock-period: uint, + cooldown-start: (optional uint), + accumulated-rewards: uint + } +) + +;; Tier System Configuration +(define-map TierLevels + uint + { + minimum-stake: uint, + reward-multiplier: uint, + features-enabled: (list 10 bool) + } +) + +;; Public Functions + +;; Contract Administration +(define-public (initialize-contract) + (begin + (asserts! (is-eq tx-sender CONTRACT-OWNER) ERR-NOT-AUTHORIZED) + + ;; Set up tier levels + (map-set TierLevels u1 + { + minimum-stake: u1000000, + reward-multiplier: u100, + features-enabled: (list true false false false false false false false false false) + }) + (map-set TierLevels u2 + { + minimum-stake: u5000000, + reward-multiplier: u150, + features-enabled: (list true true true false false false false false false false) + }) + (map-set TierLevels u3 + { + minimum-stake: u10000000, + reward-multiplier: u200, + features-enabled: (list true true true true true false false false false false) + }) + (ok true) + ) ) \ No newline at end of file From 310a2f2e67cecb922d8c65dfb8af6068029d83ee Mon Sep 17 00:00:00 2001 From: david-cmd-byte Date: Sun, 9 Mar 2025 09:34:09 +0100 Subject: [PATCH 3/7] feat: Implement staking operations - Add `stake-stx` public function to allow users to stake STX tokens with a specified lock period. - Validate lock period, contract status, and minimum stake amount. - Transfer STX tokens from user to contract. - Update `StakingPositions` and `UserPositions` maps with new staking details. - Adjust user's tier level and rewards multiplier based on the new total stake and lock period. - Update the STX pool with the staked amount. --- contracts/analytics-token.clar | 60 ++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/contracts/analytics-token.clar b/contracts/analytics-token.clar index 4bd0a70..e0ab214 100644 --- a/contracts/analytics-token.clar +++ b/contracts/analytics-token.clar @@ -118,4 +118,64 @@ }) (ok true) ) +) + +;; Staking Operations +(define-public (stake-stx (amount uint) (lock-period uint)) + (let + ( + (current-position (default-to + { + total-collateral: u0, + total-debt: u0, + health-factor: u0, + last-updated: u0, + stx-staked: u0, + analytics-tokens: u0, + voting-power: u0, + tier-level: u0, + rewards-multiplier: u100 + } + (map-get? UserPositions tx-sender))) + ) + (asserts! (is-valid-lock-period lock-period) ERR-INVALID-PROTOCOL) + (asserts! (not (var-get contract-paused)) ERR-PAUSED) + (asserts! (>= amount (var-get minimum-stake)) ERR-BELOW-MINIMUM) + + (try! (stx-transfer? amount tx-sender (as-contract tx-sender))) + + (let + ( + (new-total-stake (+ (get stx-staked current-position) amount)) + (tier-info (get-tier-info new-total-stake)) + (lock-multiplier (calculate-lock-multiplier lock-period)) + ) + + (map-set StakingPositions + tx-sender + { + amount: amount, + start-block: block-height, + last-claim: block-height, + lock-period: lock-period, + cooldown-start: none, + accumulated-rewards: u0 + } + ) + + (map-set UserPositions + tx-sender + (merge current-position + { + stx-staked: new-total-stake, + tier-level: (get tier-level tier-info), + rewards-multiplier: (* (get reward-multiplier tier-info) lock-multiplier) + } + ) + ) + + (var-set stx-pool (+ (var-get stx-pool) amount)) + (ok true) + ) + ) ) \ No newline at end of file From b5ac194041471f305def0d9aef77589af9d733c6 Mon Sep 17 00:00:00 2001 From: david-cmd-byte Date: Sun, 9 Mar 2025 09:37:04 +0100 Subject: [PATCH 4/7] feat: Add unstaking and governance operations - Implement `initiate-unstake` public function to start the unstaking process by setting the cooldown start block. - Implement `complete-unstake` public function to complete the unstaking process after the cooldown period and transfer STX back to the user. - Implement `create-proposal` public function to allow users to create governance proposals with a description and voting period. - Validate user authorization, description, and voting period for proposals. - Update `Proposals` map and increment proposal count. --- contracts/analytics-token.clar | 67 ++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/contracts/analytics-token.clar b/contracts/analytics-token.clar index e0ab214..37533a1 100644 --- a/contracts/analytics-token.clar +++ b/contracts/analytics-token.clar @@ -178,4 +178,71 @@ (ok true) ) ) +) + +;; Unstaking Operations +(define-public (initiate-unstake (amount uint)) + (let + ( + (staking-position (unwrap! (map-get? StakingPositions tx-sender) ERR-NO-STAKE)) + (current-amount (get amount staking-position)) + ) + (asserts! (>= current-amount amount) ERR-INSUFFICIENT-STX) + (asserts! (is-none (get cooldown-start staking-position)) ERR-COOLDOWN-ACTIVE) + + (map-set StakingPositions + tx-sender + (merge staking-position + { + cooldown-start: (some block-height) + } + ) + ) + (ok true) + ) +) + +(define-public (complete-unstake) + (let + ( + (staking-position (unwrap! (map-get? StakingPositions tx-sender) ERR-NO-STAKE)) + (cooldown-start (unwrap! (get cooldown-start staking-position) ERR-NOT-AUTHORIZED)) + ) + (asserts! (>= (- block-height cooldown-start) (var-get cooldown-period)) ERR-COOLDOWN-ACTIVE) + + (try! (as-contract (stx-transfer? (get amount staking-position) tx-sender tx-sender))) + + (map-delete StakingPositions tx-sender) + + (ok true) + ) +) + +;; Governance Operations +(define-public (create-proposal (description (string-utf8 256)) (voting-period uint)) + (let + ( + (user-position (unwrap! (map-get? UserPositions tx-sender) ERR-NOT-AUTHORIZED)) + (proposal-id (+ (var-get proposal-count) u1)) + ) + (asserts! (>= (get voting-power user-position) u1000000) ERR-NOT-AUTHORIZED) + (asserts! (is-valid-description description) ERR-INVALID-PROTOCOL) + (asserts! (is-valid-voting-period voting-period) ERR-INVALID-PROTOCOL) + + (map-set Proposals { proposal-id: proposal-id } + { + creator: tx-sender, + description: description, + start-block: block-height, + end-block: (+ block-height voting-period), + executed: false, + votes-for: u0, + votes-against: u0, + minimum-votes: u1000000 + } + ) + + (var-set proposal-count proposal-id) + (ok proposal-id) + ) ) \ No newline at end of file From 99c13e5b676a466130ee57ca4f1f9978cb0121de Mon Sep 17 00:00:00 2001 From: david-cmd-byte Date: Sun, 9 Mar 2025 13:17:09 +0100 Subject: [PATCH 5/7] feat: Add voting, contract control, and read-only functions - Implement `vote-on-proposal` public function to allow users to vote on governance proposals. - Validate proposal existence, voting period, and user authorization. - Update proposal votes based on user input. - Implement `pause-contract` and `resume-contract` public functions to allow the contract owner to pause and resume the contract. - Implement read-only functions `get-contract-owner`, `get-stx-pool`, and `get-proposal-count` to retrieve contract owner, STX pool balance, and proposal count. - Add private functions `get-tier-info` and `calculate-lock-multiplier` to determine tier level and reward multiplier based on stake amount and lock period. --- contracts/analytics-token.clar | 79 +++++++++++++++++++++++++++++++++- 1 file changed, 78 insertions(+), 1 deletion(-) diff --git a/contracts/analytics-token.clar b/contracts/analytics-token.clar index 37533a1..34930d9 100644 --- a/contracts/analytics-token.clar +++ b/contracts/analytics-token.clar @@ -245,4 +245,81 @@ (var-set proposal-count proposal-id) (ok proposal-id) ) -) \ No newline at end of file +) + +(define-public (vote-on-proposal (proposal-id uint) (vote-for bool)) + (let + ( + (proposal (unwrap! (map-get? Proposals { proposal-id: proposal-id }) ERR-INVALID-PROTOCOL)) + (user-position (unwrap! (map-get? UserPositions tx-sender) ERR-NOT-AUTHORIZED)) + (voting-power (get voting-power user-position)) + (max-proposal-id (var-get proposal-count)) + ) + (asserts! (< block-height (get end-block proposal)) ERR-NOT-AUTHORIZED) + (asserts! (and (> proposal-id u0) (<= proposal-id max-proposal-id)) ERR-INVALID-PROTOCOL) + + (map-set Proposals { proposal-id: proposal-id } + (merge proposal + { + votes-for: (if vote-for (+ (get votes-for proposal) voting-power) (get votes-for proposal)), + votes-against: (if vote-for (get votes-against proposal) (+ (get votes-against proposal) voting-power)) + } + ) + ) + (ok true) + ) +) + +;; Contract Control +(define-public (pause-contract) + (begin + (asserts! (is-eq tx-sender CONTRACT-OWNER) ERR-NOT-AUTHORIZED) + (var-set contract-paused true) + (ok true) + ) +) + +(define-public (resume-contract) + (begin + (asserts! (is-eq tx-sender CONTRACT-OWNER) ERR-NOT-AUTHORIZED) + (var-set contract-paused false) + (ok true) + ) +) + +;; Read-Only Functions + +(define-read-only (get-contract-owner) + (ok CONTRACT-OWNER) +) + +(define-read-only (get-stx-pool) + (ok (var-get stx-pool)) +) + +(define-read-only (get-proposal-count) + (ok (var-get proposal-count)) +) + +;; Private Functions + +(define-private (get-tier-info (stake-amount uint)) + (if (>= stake-amount u10000000) + {tier-level: u3, reward-multiplier: u200} + (if (>= stake-amount u5000000) + {tier-level: u2, reward-multiplier: u150} + {tier-level: u1, reward-multiplier: u100} + ) + ) +) + +(define-private (calculate-lock-multiplier (lock-period uint)) + (if (>= lock-period u8640) ;; 2 months + u150 ;; 1.5x multiplier + (if (>= lock-period u4320) ;; 1 month + u125 ;; 1.25x multiplier + u100 ;; 1x multiplier (no lock) + ) + ) +) + From 4d58d6e95dd66bc23003de886b27ef30500c1f5c Mon Sep 17 00:00:00 2001 From: david-cmd-byte Date: Sun, 9 Mar 2025 13:18:18 +0100 Subject: [PATCH 6/7] feat: Add reward calculation and validation functions - Implement `calculate-rewards` private function to calculate rewards based on user's stake amount, base rate, multiplier, and number of blocks. - Implement `is-valid-description` private function to validate proposal descriptions ensuring they meet length requirements. - Implement `is-valid-lock-period` private function to validate lock periods ensuring they match predefined durations. - Implement `is-valid-voting-period` private function to validate voting periods ensuring they fall within acceptable range. --- contracts/analytics-token.clar | 48 +++++++++++++++++++++++++++++----- 1 file changed, 41 insertions(+), 7 deletions(-) diff --git a/contracts/analytics-token.clar b/contracts/analytics-token.clar index 34930d9..e759e8b 100644 --- a/contracts/analytics-token.clar +++ b/contracts/analytics-token.clar @@ -155,8 +155,8 @@ tx-sender { amount: amount, - start-block: block-height, - last-claim: block-height, + start-block: stacks-block-height, + last-claim: stacks-block-height, lock-period: lock-period, cooldown-start: none, accumulated-rewards: u0 @@ -194,7 +194,7 @@ tx-sender (merge staking-position { - cooldown-start: (some block-height) + cooldown-start: (some stacks-block-height) } ) ) @@ -208,7 +208,7 @@ (staking-position (unwrap! (map-get? StakingPositions tx-sender) ERR-NO-STAKE)) (cooldown-start (unwrap! (get cooldown-start staking-position) ERR-NOT-AUTHORIZED)) ) - (asserts! (>= (- block-height cooldown-start) (var-get cooldown-period)) ERR-COOLDOWN-ACTIVE) + (asserts! (>= (- stacks-block-height cooldown-start) (var-get cooldown-period)) ERR-COOLDOWN-ACTIVE) (try! (as-contract (stx-transfer? (get amount staking-position) tx-sender tx-sender))) @@ -233,8 +233,8 @@ { creator: tx-sender, description: description, - start-block: block-height, - end-block: (+ block-height voting-period), + start-block: stacks-block-height, + end-block: (+ stacks-block-height voting-period), executed: false, votes-for: u0, votes-against: u0, @@ -255,7 +255,7 @@ (voting-power (get voting-power user-position)) (max-proposal-id (var-get proposal-count)) ) - (asserts! (< block-height (get end-block proposal)) ERR-NOT-AUTHORIZED) + (asserts! (< stacks-block-height (get end-block proposal)) ERR-NOT-AUTHORIZED) (asserts! (and (> proposal-id u0) (<= proposal-id max-proposal-id)) ERR-INVALID-PROTOCOL) (map-set Proposals { proposal-id: proposal-id } @@ -323,3 +323,37 @@ ) ) +(define-private (calculate-rewards (user principal) (blocks uint)) + (let + ( + (staking-position (unwrap! (map-get? StakingPositions user) u0)) + (user-position (unwrap! (map-get? UserPositions user) u0)) + (stake-amount (get amount staking-position)) + (base-rate (var-get base-reward-rate)) + (multiplier (get rewards-multiplier user-position)) + ) + (/ (* (* (* stake-amount base-rate) multiplier) blocks) u14400000) + ) +) + +(define-private (is-valid-description (desc (string-utf8 256))) + (and + (>= (len desc) u10) + (<= (len desc) u256) + ) +) + +(define-private (is-valid-lock-period (lock-period uint)) + (or + (is-eq lock-period u0) + (is-eq lock-period u4320) + (is-eq lock-period u8640) + ) +) + +(define-private (is-valid-voting-period (period uint)) + (and + (>= period u100) + (<= period u2880) + ) +) \ No newline at end of file From c1f3ace52c183f0403e6429633ec29fba3d90816 Mon Sep 17 00:00:00 2001 From: david-cmd-byte Date: Sun, 9 Mar 2025 13:22:46 +0100 Subject: [PATCH 7/7] docs: Add README for Analytics Token Staking & Governance Contract - Provide an overview of the contract's purpose and key features. - Include instructions for deploying and interacting with the contract. - Document public functions, data maps, and error codes. --- README.md | 130 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..194cb12 --- /dev/null +++ b/README.md @@ -0,0 +1,130 @@ +# Analytics Token Staking & Governance Contract + +**Version**: 1.0.0 + +### **Overview** + +This Clarity smart contract enables users to stake STX tokens to earn **ANALYTICS-TOKEN** rewards and participate in protocol governance. The system features a tiered staking mechanism with dynamic rewards, voting power scaling, and administrative safeguards. Designed for decentralized analytics platforms, it incentivizes long-term participation while ensuring community-driven protocol updates. + +### **Key Features** + +1. **Tiered Staking System** + + - **Tiers**: 3 levels (Bronze, Silver, Gold) based on STX staked. + - **Reward Multipliers**: + - Bronze (1M+ STX): 1x base rewards + - Silver (5M+ STX): 1.5x rewards + governance features + - Gold (10M+ STX): 2x rewards + full governance rights + +2. **Lock-Up Bonuses** + + - Optional lock periods (0, 30, 60 days) boost rewards by 1.25x–1.5x. + +3. **Governance Engine** + + - Create/veto proposals with voting power proportional to staked STX. + - Minimum 1M STX staked to propose governance actions. + +4. **Security Protections** + - 24-hour cooldown for unstaking. + - Emergency pause/resume functions. + - Penalty-free withdrawals post-cooldown. + +### **Technical Specifications** + +#### **Constants** + +- `CONTRACT-OWNER`: Admin address with pause/resume privileges. +- `minimum-stake`: 1,000,000 STX (1 STX = 1e6 units). +- `cooldown-period`: 1,440 blocks (~24 hours). + +#### **Reward Formula** + +``` +Rewards = (staked_amount × base_rate × multiplier × elapsed_blocks) / 14,400,000 +``` + +- **Base Rate**: 5% APY (adjustable via governance). +- **Multiplier**: Tier + lock-period bonuses. + +#### **Data Structures** + +- `UserPositions`: Tiers, STX staked, voting power, rewards. +- `StakingPositions`: Lock periods, cooldown timers, accrued rewards. +- `Proposals`: Voting deadlines, vote counts, execution status. + +### **Core Functions** + +#### **Staking** + +1. **`stake-stx`**: Lock STX to earn rewards. + + - Inputs: `amount` (STX), `lock-period` (0/4,320/8,640 blocks). + - Requirements: Minimum 1M STX, valid lock period. + +2. **`initiate-unstake`**: Start 24-hour cooldown. +3. **`complete-unstake`**: Withdraw STX post-cooldown. + +#### **Governance** + +1. **`create-proposal`**: Submit governance action (e.g., reward rate changes). + + - Requires ≥1M STX staked. + - Inputs: `description` (256 chars), `voting-period` (100–2,880 blocks). + +2. **`vote-on-proposal`**: Cast votes using staking-derived voting power. + +#### **Administration** + +- **`pause-contract`/**`resume-contract`\*\*: Freeze/all operations (owner-only). + +### **Governance Process** + +1. **Proposal Creation** + + - Submit description + voting window. + - Minimum 1M STX staked required. + +2. **Voting Phase** + + - Votes weighted by `voting-power` (1 STX = 1 vote). + - Proposals pass if: + - `votes-for > votes-against` + - Total votes ≥ `minimum-votes` (1M). + +3. **Execution** + - Successful proposals executable after `end-block`. + +### **Security & Error Handling** + +#### **Error Codes** + +- `ERR-NOT-AUTHORIZED` (1000): Unauthorized action. +- `ERR-INSUFFICIENT-STX` (1003): Insufficient staked balance. +- `ERR-COOLDOWN-ACTIVE` (1004): Premature withdrawal attempt. + +#### **Emergency Protocols** + +- **Pause Mode**: Halts all staking/unstaking during threats. +- **Audited Withdrawals**: STX refunds guaranteed post-cooldown. + +### **Integration Guide** + +#### **Dependencies** + +- Clarinet (local testing). +- Hiro Explorer (mainnet deployment). + +#### **Sample Interactions** + +**Stake STX (30-Day Lock):** + +```clarity +(contract-call? .analytics-staking-contract stake-stx u5000000 u4320) +``` + +**Create Proposal:** + +```clarity +(contract-call? .analytics-staking-contract create-proposal "Increase base reward rate to 6%" u1000) +```