Source Code

;; Bridge Fee Calculator Contract
;; Dynamic fee calculation for sBTC bridge operations
;; Adjusts fees based on network congestion and BTC mempool

(define-constant contract-owner tx-sender)
(define-constant err-owner-only (err u200))
(define-constant err-not-authorized (err u201))
(define-constant err-invalid-amount (err u202))
(define-constant err-invalid-fee (err u203))

(define-constant BASE-FEE-BPS u30)      ;; 0.3% base fee
(define-constant MIN-FEE u1000)         ;; 1000 sats minimum
(define-constant MAX-FEE-BPS u200)      ;; 2% max fee
(define-constant FEE-DENOMINATOR u10000)

(define-data-var current-fee-bps uint BASE-FEE-BPS)
(define-data-var congestion-multiplier uint u100) ;; 100 = 1x
(define-data-var fee-collector principal contract-owner)
(define-data-var total-fees-collected uint u0)
(define-data-var calculation-count uint u0)

(define-map fee-tiers uint
  {
    min-amount: uint,
    max-amount: uint,
    fee-bps: uint
  }
)

(define-map fee-history uint
  {
    amount: uint,
    fee: uint,
    fee-bps: uint,
    block-height: uint,
    direction: (string-ascii 10)
  }
)

;; Read-only
(define-read-only (get-current-fee-bps)
  (var-get current-fee-bps)
)

(define-read-only (get-fee-tier (tier-id uint))
  (map-get? fee-tiers tier-id)
)

(define-read-only (calculate-bridge-fee (amount uint) (direction (string-ascii 10)))
  (let (
    (base-fee (/ (* amount (var-get current-fee-bps)) FEE-DENOMINATOR))
    (adjusted-fee (/ (* base-fee (var-get congestion-multiplier)) u100))
    (final-fee (if (< adjusted-fee MIN-FEE) MIN-FEE adjusted-fee))
  )
    (ok { amount: amount, fee: final-fee, fee-bps: (var-get current-fee-bps), net-amount: (- amount final-fee) })
  )
)

(define-read-only (get-total-fees-collected)
  (var-get total-fees-collected)
)

(define-read-only (get-congestion-multiplier)
  (var-get congestion-multiplier)
)

;; Public functions
(define-public (set-fee-bps (new-fee-bps uint))
  (begin
    (asserts! (is-eq tx-sender contract-owner) err-owner-only)
    (asserts! (<= new-fee-bps MAX-FEE-BPS) err-invalid-fee)
    (var-set current-fee-bps new-fee-bps)
    (ok new-fee-bps)
  )
)

(define-public (set-congestion-multiplier (multiplier uint))
  (begin
    (asserts! (is-eq tx-sender contract-owner) err-owner-only)
    (asserts! (and (>= multiplier u50) (<= multiplier u300)) err-invalid-fee)
    (var-set congestion-multiplier multiplier)
    (ok multiplier)
  )
)

(define-public (set-fee-tier (tier-id uint) (min-amount uint) (max-amount uint) (fee-bps uint))
  (begin
    (asserts! (is-eq tx-sender contract-owner) err-owner-only)
    (asserts! (<= fee-bps MAX-FEE-BPS) err-invalid-fee)
    (map-set fee-tiers tier-id { min-amount: min-amount, max-amount: max-amount, fee-bps: fee-bps })
    (ok tier-id)
  )
)

(define-public (record-fee-collection (amount uint) (fee uint) (direction (string-ascii 10)))
  (let ((count (var-get calculation-count)))
    (asserts! (is-eq tx-sender contract-owner) err-owner-only)
    (map-set fee-history count {
      amount: amount, fee: fee,
      fee-bps: (var-get current-fee-bps),
      block-height: stacks-block-height,
      direction: direction
    })
    (var-set total-fees-collected (+ (var-get total-fees-collected) fee))
    (var-set calculation-count (+ count u1))
    (ok { recorded: true, total-fees: (var-get total-fees-collected) })
  )
)

(define-public (set-fee-collector (collector principal))
  (begin
    (asserts! (is-eq tx-sender contract-owner) err-owner-only)
    (var-set fee-collector collector)
    (ok collector)
  )
)

Functions (10)

FunctionAccessArgs
get-current-fee-bpsread-only
get-fee-tierread-onlytier-id: uint
calculate-bridge-feeread-onlyamount: uint, direction: (string-ascii 10
get-total-fees-collectedread-only
get-congestion-multiplierread-only
set-fee-bpspublicnew-fee-bps: uint
set-congestion-multiplierpublicmultiplier: uint
set-fee-tierpublictier-id: uint, min-amount: uint, max-amount: uint, fee-bps: uint
record-fee-collectionpublicamount: uint, fee: uint, direction: (string-ascii 10
set-fee-collectorpubliccollector: principal