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