Source Code

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(use-trait ft-trait 'SP2AKWJYC7BNY18W1XXKPGP0YVEK63QJG4793Z2D4.sip-010-trait-ft-standard.sip-010-trait)

(use-trait share-fee-to-trait 'SP1Y5YSTAHZ88XYK1VPDH24GY0HPX5J4JECTMY4A1.univ2-share-fee-to-trait.share-fee-to-trait)

(use-trait univ2v2-pool-trait 'SP1Y5YSTAHZ88XYK1VPDH24GY0HPX5J4JECTMY4A1.univ2-pool-trait_v1_0_0.univ2-pool-trait)
(use-trait univ2v2-fees-trait 'SP1Y5YSTAHZ88XYK1VPDH24GY0HPX5J4JECTMY4A1.univ2-fees-trait_v1_0_0.univ2-fees-trait)

(use-trait curve-pool-trait   'SP1Y5YSTAHZ88XYK1VPDH24GY0HPX5J4JECTMY4A1.curve-pool-trait_v1_0_0.curve-pool-trait)
(use-trait curve-fees-trait   'SP1Y5YSTAHZ88XYK1VPDH24GY0HPX5J4JECTMY4A1.curve-fees-trait_v1_0_0.curve-fees-trait)

(use-trait ststx-pool-trait   'SP20X3DC5R091J8B6YPQT638J8NR1W83KN6TN5BJY.curve-pool-trait_ststx.curve-pool-trait)
(use-trait ststx-proxy-trait  'SP20X3DC5R091J8B6YPQT638J8NR1W83KN6TN5BJY.curve-proxy-trait_ststx.curve-proxy-trait)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; max 2047 edge tuples
(define-constant MAX-EDGES    u500) ;;effectively max nr of pools (stx -> *)
(define-constant MAX-PATH-LEN u4)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; pool types
(define-constant UNIV2   "u")
(define-constant UNIV2V2 "v")
(define-constant CURVE   "c")
(define-constant USDH    "h")
(define-constant STSTX   "s")

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; edges
(define-read-only
  (is-univ2 (edge {a:(string-ascii 1),b:principal,c:uint,d:principal,e:principal,f:bool}))
  (is-eq (get a edge) UNIV2))
(define-read-only
  (is-univ2v2 (edge {a:(string-ascii 1),b:principal,c:uint,d:principal,e:principal,f:bool}))
  (is-eq (get a edge) UNIV2V2))
(define-read-only
  (is-curve (edge {a:(string-ascii 1),b:principal,c:uint,d:principal,e:principal,f:bool}))
  (is-eq (get a edge) CURVE))
(define-read-only
 (is-usdh (edge {a:(string-ascii 1),b:principal,c:uint,d:principal,e:principal,f:bool}))
 (is-eq (get a edge) USDH))
(define-read-only
  (is-ststx (edge {a:(string-ascii 1),b:principal,c:uint,d:principal,e:principal,f:bool}))
  (is-eq (get a edge) STSTX))

(define-read-only
 (id (edge {a:(string-ascii 1),b:principal,c:uint,d:principal,e:principal,f:bool}))
 (get c edge))
(define-read-only
 (from-is-token0 (edge {a:(string-ascii 1),b:principal,c:uint,d:principal,e:principal,f:bool}))
 (get f edge))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define-public
  (apply
   (path   (list 4 {a:(string-ascii 1),b:principal,c:uint,d:principal,e:principal,f:bool}))
   (amt-in uint)

   ;; ctx
   (token1         (optional <ft-trait>))
   (token2         (optional <ft-trait>))
   (token3         (optional <ft-trait>))
   (token4         (optional <ft-trait>))
   (token5         (optional <ft-trait>))

   ;; v1
   (share-fee-to   (optional <share-fee-to-trait>))

   ;; v2
   (univ2v2-pool-1 (optional <univ2v2-pool-trait>))
   (univ2v2-pool-2 (optional <univ2v2-pool-trait>))
   (univ2v2-pool-3 (optional <univ2v2-pool-trait>))
   (univ2v2-pool-4 (optional <univ2v2-pool-trait>))

   (univ2v2-fees-1 (optional <univ2v2-fees-trait>))
   (univ2v2-fees-2 (optional <univ2v2-fees-trait>))
   (univ2v2-fees-3 (optional <univ2v2-fees-trait>))
   (univ2v2-fees-4 (optional <univ2v2-fees-trait>))

   (curve-pool-1   (optional <curve-pool-trait>))
   (curve-pool-2   (optional <curve-pool-trait>))
   (curve-pool-3   (optional <curve-pool-trait>))
   (curve-pool-4   (optional <curve-pool-trait>))

   (curve-fees-1   (optional <curve-fees-trait>))
   (curve-fees-2   (optional <curve-fees-trait>))
   (curve-fees-3   (optional <curve-fees-trait>))
   (curve-fees-4   (optional <curve-fees-trait>))

   (ststx-pool-1   (optional <ststx-pool-trait>))
   (ststx-pool-2   (optional <ststx-pool-trait>))
   (ststx-pool-3   (optional <ststx-pool-trait>))
   (ststx-pool-4   (optional <ststx-pool-trait>))

   (ststx-proxy-1   (optional <ststx-proxy-trait>))
   (ststx-proxy-2   (optional <ststx-proxy-trait>))
   (ststx-proxy-3   (optional <ststx-proxy-trait>))
   (ststx-proxy-4   (optional <ststx-proxy-trait>))
   )
  (let ((swap1 (try! (swap (element-at? path u0) amt-in
                           token1 token2
                           share-fee-to
                           univ2v2-pool-1 univ2v2-fees-1
                           curve-pool-1 curve-fees-1
                           ststx-pool-1 ststx-proxy-1
                           )))
        (swap2 (try! (swap (element-at? path u1) (get amt-out swap1)
                           token2 token3
                           share-fee-to
                           univ2v2-pool-2 univ2v2-fees-2
                           curve-pool-2 curve-fees-2
                           ststx-pool-2 ststx-proxy-2
                           )))
        (swap3 (try! (swap (element-at? path u2) (get amt-out swap2)
                           token3 token4
                           share-fee-to
                           univ2v2-pool-3 univ2v2-fees-3
                           curve-pool-3 curve-fees-3
                           ststx-pool-3 ststx-proxy-3
                           )))
        (swap4 (try! (swap (element-at? path u3) (get amt-out swap3)
                           token4 token5
                           share-fee-to
                           univ2v2-pool-4 univ2v2-fees-4
                           curve-pool-4 curve-fees-4
                           ststx-pool-4 ststx-proxy-4
                           )))
        )
    (ok
    {swap1: swap1,
     swap2: swap2,
     swap3: swap3,
     swap4: swap4,
    }) ))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define-private
  (swap
   (edge   (optional {a:(string-ascii 1),b:principal,c:uint,d:principal,e:principal,f:bool}))
   (amt-in uint)

   (token-in     (optional <ft-trait>))
   (token-out    (optional <ft-trait>))
   (share-fee-to (optional <share-fee-to-trait>))
   (univ2v2-pool (optional <univ2v2-pool-trait>))
   (univ2v2-fees (optional <univ2v2-fees-trait>))
   (curve-pool   (optional <curve-pool-trait>))
   (curve-fees   (optional <curve-fees-trait>))
   (ststx-pool   (optional <ststx-pool-trait>))
   (ststx-proxy  (optional <ststx-proxy-trait>))

   )
  (match
   edge
   e
    (if (is-univ2   e) (swap-univ2   e amt-in
                                     (unwrap-panic token-in) (unwrap-panic token-out)
                                     (unwrap-panic share-fee-to))
    (if (is-univ2v2 e) (swap-univ2v2 e amt-in
                                     (unwrap-panic token-in) (unwrap-panic token-out)
                                     (unwrap-panic univ2v2-pool) (unwrap-panic univ2v2-fees))
    (if (is-curve   e) (swap-curve   e amt-in
                                     (unwrap-panic token-in) (unwrap-panic token-out)
                                     (unwrap-panic curve-pool) (unwrap-panic curve-fees))
    (if (is-usdh    e) (swap-curve   e amt-in
                                     (unwrap-panic token-in) (unwrap-panic token-out)
                                     (unwrap-panic curve-pool) (unwrap-panic curve-fees))
    (if (is-ststx   e) (swap-ststx   e amt-in
                                     (unwrap-panic token-in) (unwrap-panic token-out)
                                     (unwrap-panic ststx-pool) (unwrap-panic curve-fees)
                                     (unwrap-panic ststx-proxy))

    (err u0))))))
   (ok {amt-in: amt-in, amt-out: amt-in}) ))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define-public
  (swap-univ2
   (edge         {a:(string-ascii 1),b:principal,c:uint,d:principal,e:principal,f:bool})
   (amt-in       uint)
   (token-in     <ft-trait>)
   (token-out    <ft-trait>)
   (share-fee-to <share-fee-to-trait>) )
  (let ((res
         (try!
          (contract-call?
           'SP1Y5YSTAHZ88XYK1VPDH24GY0HPX5J4JECTMY4A1.univ2-router
           swap-exact-tokens-for-tokens
           (id edge)
           (if (from-is-token0 edge) token-in token-out)
           (if (from-is-token0 edge) token-out token-in)
           token-in
           token-out
           share-fee-to
           amt-in
           u1 ;;amt-out-min
           ))))
    (ok {amt-in: amt-in, amt-out: (get amt-out res)}) ))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define-public
  (swap-univ2v2
   (edge         {a:(string-ascii 1),b:principal,c:uint,d:principal,e:principal,f:bool})
   (amt-in       uint)
   (token-in     <ft-trait>)
   (token-out    <ft-trait>)
   (univ2v2-pool <univ2v2-pool-trait>)
   (univ2v2-fees <univ2v2-fees-trait>)
   )
  (let ((res
         (try!
          (contract-call?
           univ2v2-pool
           swap
           token-in
           token-out
           univ2v2-fees
           amt-in
           u1 ;;amt-out-min
           ))))
    (ok {amt-in: amt-in, amt-out: (get amt-out res)}) ))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define-public
  (swap-curve
   (edge         {a:(string-ascii 1),b:principal,c:uint,d:principal,e:principal,f:bool})
   (amt-in       uint)
   (token-in     <ft-trait>)
   (token-out    <ft-trait>)
   (curve-pool   <curve-pool-trait>)
   (curve-fees   <curve-fees-trait>)
   )
  (let ((res (try! (contract-call?
                      curve-pool
                      swap
                      token-in
                      token-out
                      curve-fees
                      amt-in
                      u1 ;;amt-out-min
                      ))))
    (ok {amt-in: amt-in, amt-out: (get amt-out res)}) ))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define-public
 (swap-ststx
  (edge         {a:(string-ascii 1),b:principal,c:uint,d:principal,e:principal,f:bool})
  (amt-in       uint)
  (token-in     <ft-trait>)
  (token-out    <ft-trait>)
  (ststx-pool   <ststx-pool-trait>)
  (curve-fees   <curve-fees-trait>)
  (ststx-proxy  <ststx-proxy-trait>)
  )
 (let ((res (try! (contract-call?
                   ststx-pool
                   swap
                   token-in
                   token-out
                   curve-fees
                   ststx-proxy
                   amt-in
                   u1 ;;amt-out-min
                   ))))
   (ok {amt-in: amt-in, amt-out: (get amt-out res)}) ))

;;; eof