Source Code

;; ========================================
;; VAULTAYIELD - STACKING STRATEGY
;; ========================================
;; Manages STX stacking lifecycle via PoX delegation
;; Handles cycle tracking, lock periods, and pool coordination

;; ========================================
;; CONSTANTS
;; ========================================

(define-constant CONTRACT-OWNER tx-sender)

;; Error codes
(define-constant ERR-NOT-AUTHORIZED (err u100))
(define-constant ERR-ALREADY-STACKING (err u101))
(define-constant ERR-INSUFFICIENT-AMOUNT (err u102))
(define-constant ERR-INVALID-CYCLES (err u103))
(define-constant ERR-LOCKED (err u104))
(define-constant ERR-NOT-STACKING (err u105))
(define-constant ERR-INVALID-POOL (err u106))

;; Stacking constraints
(define-constant MIN-STACKING-AMOUNT u100000000000) ;; 100K STX (100B micro-STX)
(define-constant MAX-CYCLES u12)
(define-constant MIN-CYCLES u1)

;; ========================================
;; DATA VARIABLES  
;; ========================================

;; Pool operator who aggregates and stakes our STX
(define-data-var pool-operator (optional principal) none)

;; Current stacking cycle information
(define-data-var current-cycle uint u0)
(define-data-var stacked-amount uint u0)
(define-data-var unlock-cycle uint u0)

;; Stacking status tracking
(define-data-var is-stacking bool false)

;; Phase 3: Will add BTC reward address configuration

;; Authorized vault-core contract
(define-data-var vault-core-contract (optional principal) none)

;; ========================================
;; READ-ONLY FUNCTIONS
;; ========================================

(define-read-only (get-stacking-status)
  ;; Return current stacking state
  {
    is-stacking: (var-get is-stacking),
    amount: (var-get stacked-amount),
    unlock-cycle: (var-get unlock-cycle),
    current-cycle: (var-get current-cycle),
    pool-operator: (var-get pool-operator)
  }
)

(define-read-only (is-unlocked)
  ;; Check if STX can be withdrawn
  ;; Returns true if not stacking OR past unlock cycle
  (if (var-get is-stacking)
    (>= (var-get current-cycle) (var-get unlock-cycle))
    true
  )
)

(define-read-only (get-pool-operator)
  ;; Return current pool operator
  (var-get pool-operator)
)

(define-read-only (get-stacked-amount)
  ;; Return amount currently stacked
  (var-get stacked-amount)
)

(define-read-only (get-unlock-cycle)
  ;; Return cycle when STX will unlock
  (var-get unlock-cycle)
)

;; ========================================
;; PRIVATE FUNCTIONS
;; ========================================

(define-private (is-authorized-vault)
  ;; Check if caller is authorized vault-core contract
  (match (var-get vault-core-contract)
    vault-contract (is-eq contract-caller vault-contract)
    false
  )
)

;; ========================================
;; PUBLIC FUNCTIONS - Placeholder Stubs
;; ========================================
;; Full implementation will follow in subsequent commits

(define-public (delegate-vault-stx (amount uint) (cycles uint))
  ;; Delegate STX to pool operator for PoX stacking
  ;; Only callable by authorized vault-core contract
  (let
    (
      (operator (var-get pool-operator))
      (current-stacking (var-get is-stacking))
    )
    ;; Validation checks
    (asserts! (is-authorized-vault) ERR-NOT-AUTHORIZED)
    (asserts! (not current-stacking) ERR-ALREADY-STACKING)
    (asserts! (>= amount MIN-STACKING-AMOUNT) ERR-INSUFFICIENT-AMOUNT)
    (asserts! (and (>= cycles MIN-CYCLES) (<= cycles MAX-CYCLES)) ERR-INVALID-CYCLES)
    (asserts! (is-some operator) ERR-INVALID-POOL)
    
    ;; Update stacking state
    (var-set is-stacking true)
    (var-set stacked-amount amount)
    
    ;; Calculate unlock cycle (current + cycles)
    ;; In real implementation, would query PoX for current cycle
    ;; For now, using block height as approximation
    (let
      (
        (current-pox-cycle (/ block-height u2100)) ;; ~2100 blocks per cycle
        (new-unlock-cycle (+ current-pox-cycle cycles))
      )
      (var-set current-cycle current-pox-cycle)
      (var-set unlock-cycle new-unlock-cycle)
      
      ;; Emit stacking event
      (print {
        event: "stacking-initiated",
        amount: amount,
        cycles: cycles,
        unlock-cycle: new-unlock-cycle,
        pool-operator: operator,
        timestamp: block-height
      })
      
      ;; TODO: Integrate with PoX-4 delegate-stx function
      ;; (contract-call? 'ST000000000000000000002AMW42H.pox-4 delegate-stx
      ;;   amount
      ;;   (unwrap-panic operator)
      ;;   (unwrap-panic (some unlock-height))
      ;;   (some (var-get reward-btc-address))
      ;; )
      
      (ok true)
    )
  )
)

(define-public (revoke-delegation)
  ;; Revoke STX delegation from pool operator
  ;; Can only be called when STX is unlocked
  ;; Emergency function - admin only
  (let
    (
      (stacking-status (var-get is-stacking))
      (unlocked (is-unlocked))
    )
    ;; Validation checks
    (asserts! (is-eq tx-sender CONTRACT-OWNER) ERR-NOT-AUTHORIZED)
    (asserts! stacking-status ERR-NOT-STACKING)
    (asserts! unlocked ERR-LOCKED)
    
    ;; Reset stacking state
    (var-set is-stacking false)
    (var-set stacked-amount u0)
    (var-set unlock-cycle u0)
    
    ;; Emit revocation event
    (print {
      event: "delegation-revoked",
      previous-amount: (var-get stacked-amount),
      revoked-at-cycle: (var-get current-cycle),
      timestamp: block-height
    })
    
    ;; TODO: Integrate with PoX-4 revoke-delegate-stx function
    ;; (contract-call? 'ST000000000000000000002AMW42H.pox-4 revoke-delegate-stx)
    
    (ok true)
  )
)

(define-public (update-pool-operator (new-operator principal))
  ;; Change pool operator address
  ;; Cannot change during active stacking period
  ;; Admin only
  (let
    (
      (currently-stacking (var-get is-stacking))
    )
    ;; Validation checks
    (asserts! (is-eq tx-sender CONTRACT-OWNER) ERR-NOT-AUTHORIZED)
    (asserts! (not currently-stacking) ERR-LOCKED)
    
    ;; Update pool operator
    (var-set pool-operator (some new-operator))
    
    ;; Emit update event
    (print {
      event: "pool-operator-updated",
      new-operator: new-operator,
      timestamp: block-height
    })
    
    (ok true)
  )
)

;; ========================================
;; ADMIN FUNCTIONS
;; ========================================

(define-public (set-vault-core (vault-contract principal))
  ;; Set authorized vault-core contract
  (begin
    (asserts! (is-eq tx-sender CONTRACT-OWNER) ERR-NOT-AUTHORIZED)
    (var-set vault-core-contract (some vault-contract))
    (ok true)
  )
)

;; Phase 3: Will add set-reward-btc-address function

Functions (10)

FunctionAccessArgs
get-stacking-statusread-only
is-unlockedread-only
get-pool-operatorread-only
get-stacked-amountread-only
get-unlock-cycleread-only
is-authorized-vaultprivate
delegate-vault-stxpublicamount: uint, cycles: uint
revoke-delegationpublic
update-pool-operatorpublicnew-operator: principal
set-vault-corepublicvault-contract: principal