Source Code

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; max 2047 edge tuples
(define-constant MAX-EDGES    u250) ;;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")

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 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))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; pool ctx
(define-read-only
  (reserves
   (edge {a:(string-ascii 1),b:principal,c:uint,d:principal,e:principal,f:bool})
   (pool {r0:uint,r1:uint,fee:{num:uint,den:uint},A:uint}))
  {reserve-in: (if (get f edge) (get r0 pool) (get r1 pool)),
  reserve-out: (if (get f edge) (get r1 pool) (get r0 pool))})

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define-read-only
  (eval
   (path   (list 4 {a:(string-ascii 1),b:principal,c:uint,d:principal,e:principal,f:bool}))
   (pools  (list 4 {r0:uint,r1:uint,fee:{num:uint,den:uint},A:uint}))
   (amt-in uint))
  (let ((amt-out1 (eval1 (element-at? path u0) (element-at? pools u0) amt-in))
        (amt-out2 (eval1 (element-at? path u1) (element-at? pools u1) amt-out1))
        (amt-out3 (eval1 (element-at? path u2) (element-at? pools u2) amt-out2))
        (amt-out4 (eval1 (element-at? path u3) (element-at? pools u3) amt-out3)))
    {amt-out1: amt-out1,
     amt-out2: amt-out2,
     amt-out3: amt-out3,
     amt-out4: amt-out4}))

(define-read-only
  (eval1
   (edge   (optional {a:(string-ascii 1),b:principal,c:uint,d:principal,e:principal,f:bool}))
   (pool   (optional {r0:uint,r1:uint,fee:{num:uint,den:uint},A:uint}))
   (amt-in uint))
  (if (is-none edge)
      amt-in
      (unwrap-panic (eval2 (unwrap-panic edge) (unwrap-panic pool) amt-in))))

(define-read-only
  (eval2
   (edge   {a:(string-ascii 1),b:principal,c:uint,d:principal,e:principal,f:bool})
   (pool   {r0:uint,r1:uint,fee:{num:uint,den:uint},A:uint})
   (amt-in uint))
  (if (is-univ2   edge) (eval-univ2   edge pool amt-in)
  (if (is-univ2v2 edge) (eval-univ2v2 edge pool amt-in)
  (if (is-curve   edge) (eval-curve   edge pool amt-in)
  (err u0) ))))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define-read-only
  (eval-univ2
   (edge   {a:(string-ascii 1),b:principal,c:uint,d:principal,e:principal,f:bool})
   (pool   {r0:uint,r1:uint,fee:{num:uint,den:uint},A:uint})
   (amt-in uint))
  (let ((rs (reserves edge pool))
        ;; univ2-library
        (amt-in-adjusted (/ (* amt-in (get num (get fee pool)))
                            (get den (get fee pool)) ) ))
    (ok (/ (* amt-in-adjusted (get reserve-out rs))
           (+ (get reserve-in rs) amt-in-adjusted)) ) ))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define-read-only
  (eval-univ2v2
   (edge   {a:(string-ascii 1),b:principal,c:uint,d:principal,e:principal,f:bool})
   (pool   {r0:uint,r1:uint,fee:{num:uint,den:uint},A:uint})
   (amt-in uint))
  (let ((rs (reserves edge pool))
        ;; univ2-fees/calc-fees
        (amt-in-adjusted
         (/ (* amt-in (get num (get fee pool)))
            (get den (get fee pool)))))
    (contract-call? .univ2-math find-dx
                    (get reserve-out rs) (get reserve-in rs) amt-in-adjusted)))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; TODO: curve-usdh, curve-ststx etc
(define-read-only
  (eval-curve
   (edge   {a:(string-ascii 1),b:principal,c:uint,d:principal,e:principal,f:bool})
   (pool   {r0:uint,r1:uint,fee:{num:uint,den:uint},A:uint})
   (amt-in uint))
  (let ((rs (reserves edge pool))
        ;; curve-fees/calc-fees
        (amt-in-adjusted
         (/ (* amt-in (get num (get fee pool)))
            (get den (get fee pool)))) )
    (contract-call? .curve-math_v1_0_0 find-dx
                    (get reserve-out rs) (get reserve-in rs) amt-in-adjusted
                    u0 ;;D
                    (get A pool)) ))

;;; eof