Source Code

;; SPDX-License-Identifier: BUSL-1.1

(impl-trait .alex-voting-power-trait.alex-voting-power)

(define-constant ONE_8 u100000000)
(define-constant err-get-block-info (err u1001))
(define-constant err-not-authorized (err u1000))

;; Data vars for storing pool IDs
(define-data-var voting-power-lp-pools (list 1000 uint) (list))
;; (define-data-var voting-power-surge-ids (list 200 uint) (list))

(define-private (mul-down (a uint) (b uint)) (/ (* a b) ONE_8))
(define-private (div-down (a uint) (b uint)) (if (is-eq a u0) u0 (/ (* a ONE_8) b)))

;; Authorization check
(define-read-only (is-dao-or-extension)
  (ok (asserts! (or (is-eq tx-sender 'SP102V8P0F7JX67ARQ77WEA3D3CFB5XW39REDT0AM.executor-dao) 
                    (contract-call? 'SP102V8P0F7JX67ARQ77WEA3D3CFB5XW39REDT0AM.executor-dao is-extension contract-caller)) 
                err-not-authorized)))

;; Getters for the lists
(define-read-only (get-voting-power-lp-pools)
  (var-get voting-power-lp-pools))

;; (define-read-only (get-voting-power-surge-ids)
;;   (var-get voting-power-surge-ids))

;; Governance functions to update the lists
(define-public (set-voting-power-lp-pools (pools (list 1000 uint)))
  (begin
    (try! (is-dao-or-extension))
    (ok (var-set voting-power-lp-pools pools))))

;; (define-public (set-voting-power-surge-ids (surge-ids (list 200 uint)))
;;   (begin
;;     (try! (is-dao-or-extension))
;;     (ok (var-set voting-power-surge-ids surge-ids))))

;; Helper function to calculate voting power from a single pool
(define-private (get-pool-alex-balance (pool-id uint) (address principal))
  (let ((pool-tokens (contract-call? 'SP102V8P0F7JX67ARQ77WEA3D3CFB5XW39REDT0AM.amm-registry-v2-01 get-pool-details-by-id pool-id)))
    (match pool-tokens
      success
        (let ((pool-details (unwrap-panic (contract-call? 'SP102V8P0F7JX67ARQ77WEA3D3CFB5XW39REDT0AM.amm-pool-v2-01 get-pool-details 
                                                    (get token-x success) 
                                                    (get token-y success) 
                                                    (get factor success))))
            (total-supply (unwrap-panic (contract-call? 'SP102V8P0F7JX67ARQ77WEA3D3CFB5XW39REDT0AM.token-amm-pool-v2-01 get-total-supply pool-id)))
            ;; (user-farm-details (match (contract-call? 'SP102V8P0F7JX67ARQ77WEA3D3CFB5XW39REDT0AM.alex-farming get-user-id 
            ;;                                       'SP102V8P0F7JX67ARQ77WEA3D3CFB5XW39REDT0AM.token-amm-pool-v2-01 
            ;;                                       pool-id 
            ;;                                       address)
            ;;                   some-value (contract-call? 'SP102V8P0F7JX67ARQ77WEA3D3CFB5XW39REDT0AM.alex-farming get-staker-at-cycle-or-default 
            ;;                                           'SP102V8P0F7JX67ARQ77WEA3D3CFB5XW39REDT0AM.token-amm-pool-v2-01 
            ;;                                           pool-id 
            ;;                                           (unwrap-panic (contract-call? 'SP102V8P0F7JX67ARQ77WEA3D3CFB5XW39REDT0AM.alex-farming get-reward-cycle 
            ;;                                                                       'SP102V8P0F7JX67ARQ77WEA3D3CFB5XW39REDT0AM.token-amm-pool-v2-01 
            ;;                                                                       pool-id 
            ;;                                                                       tenure-height))
            ;;                                           some-value)
            ;;                   { amount-staked: u0, to-return: u0 }))
            (user-lp-balance (unwrap-panic (contract-call? 'SP102V8P0F7JX67ARQ77WEA3D3CFB5XW39REDT0AM.token-amm-pool-v2-01 get-balance pool-id address)))
						(total-lp-balance user-lp-balance)
            ;; (total-lp-balance (+ user-lp-balance 
                              ;; (get amount-staked user-farm-details) 
                              ;; (get to-return user-farm-details)))
            (alex-from-x (if (or (is-eq (get token-x success) 'SP102V8P0F7JX67ARQ77WEA3D3CFB5XW39REDT0AM.token-alex) 
                              (is-eq (get token-x success) 'SP102V8P0F7JX67ARQ77WEA3D3CFB5XW39REDT0AM.auto-alex-v3)) 
                          (/ (* total-lp-balance (get balance-x pool-details)) total-supply) 
                          u0))
            (alex-from-y (if (or (is-eq (get token-y success) 'SP102V8P0F7JX67ARQ77WEA3D3CFB5XW39REDT0AM.token-alex) 
                              (is-eq (get token-y success) 'SP102V8P0F7JX67ARQ77WEA3D3CFB5XW39REDT0AM.auto-alex-v3)) 
                          (/ (* total-lp-balance (get balance-y pool-details)) total-supply) 
                          u0)))
        (+ alex-from-x alex-from-y))
      error u0)))

(define-private (calculate-lp-voting-power (pool-id uint) (acc { address: principal, total: uint }))
  (merge acc { total: (+ (get total acc) (get-pool-alex-balance pool-id (get address acc))) }))

;; (define-private (calculate-surge-lp-voting-power (surge-id uint) (acc { address: principal, total: uint }))
;;   (let ((staker-info (contract-call? 'SP1E0XBN9T4B10E9QMR7XMFJPMA19D77WY3KP2QKC.farming-campaign-v2-02 get-campaign-staker-or-default surge-id u0 (get address acc)))
;;         (unclaimed-amount (if (get claimed staker-info) u0 (get amount staker-info))))
;;     (merge acc { total: (+ (get total acc) unclaimed-amount) })))

(define-read-only (get-voting-power (snapshot-block uint) (address principal))
  (let ((snapshot-block-id (unwrap! (get-stacks-block-info? id-header-hash snapshot-block) err-get-block-info))
        (current-lp-pools (var-get voting-power-lp-pools))
        ;; (current-surge-ids (var-get voting-power-surge-ids))
        (total-voting-power (at-block snapshot-block-id
          (let ((alex-balance (unwrap-panic (contract-call? 'SP102V8P0F7JX67ARQ77WEA3D3CFB5XW39REDT0AM.token-alex get-balance-fixed address)))
                (auto-alex-balance (unwrap-panic (contract-call? 'SP102V8P0F7JX67ARQ77WEA3D3CFB5XW39REDT0AM.token-wlialex get-balance-fixed address)))
                (wrapped-auto-alex-balance 
                  (let ((bal-base (contract-call? 'SP102V8P0F7JX67ARQ77WEA3D3CFB5XW39REDT0AM.auto-alex-v3-wrapped get-shares-to-tokens (unwrap-panic (contract-call? 'SP102V8P0F7JX67ARQ77WEA3D3CFB5XW39REDT0AM.auto-alex-v3-wrapped get-balance address))))
                      (decimals-base (unwrap-panic (contract-call? 'SP102V8P0F7JX67ARQ77WEA3D3CFB5XW39REDT0AM.auto-alex-v3-wrapped get-decimals))))                  
                    (if (is-eq decimals-base u8) bal-base (/ (* bal-base ONE_8) (pow u10 decimals-base)))))                  
                (manual-balance (match (contract-call? 'SP102V8P0F7JX67ARQ77WEA3D3CFB5XW39REDT0AM.alex-staking-v2 get-user-id address)
                  some-value (contract-call? 'SP102V8P0F7JX67ARQ77WEA3D3CFB5XW39REDT0AM.alex-staking-v2 get-staker-at-cycle-or-default (unwrap-panic (contract-call? 'SP102V8P0F7JX67ARQ77WEA3D3CFB5XW39REDT0AM.alex-staking-v2 get-reward-cycle tenure-height)) some-value)
                  { amount-staked: u0, to-return: u0 }))
                (lp-voting-power (fold calculate-lp-voting-power current-lp-pools { address: address, total: u0 })))
                ;; (surge-voting-power (fold calculate-surge-lp-voting-power current-surge-ids { address: address, total: u0 })))
            (+ alex-balance 
               auto-alex-balance 
               (+ (get amount-staked manual-balance) (get to-return manual-balance))
               (get total lp-voting-power)
              ;;  (get total surge-voting-power)
               wrapped-auto-alex-balance)))))
    (ok total-voting-power))) 

Functions (11)

FunctionAccessArgs
mul-downprivatea: uint, b: uint
div-downprivatea: uint, b: uint
is-dao-or-extensionread-only
get-voting-power-lp-poolsread-only
get-voting-power-surge-idsread-only
set-voting-power-lp-poolspublicpools: (list 1000 uint
set-voting-power-surge-idspublicsurge-ids: (list 200 uint
get-pool-alex-balanceprivatepool-id: uint, address: principal
calculate-lp-voting-powerprivatepool-id: uint, acc: { address: principal, total: uint }
calculate-surge-lp-voting-powerprivatesurge-id: uint, acc: { address: principal, total: uint }
get-voting-powerread-onlysnapshot-block: uint, address: principal