Source Code

;;; UniswapV2Router02.sol

(use-trait ft-trait .dao-traits-v4.sip010-ft-trait)
(use-trait ft-plus-trait .dao-traits-v4.ft-plus-trait)
(use-trait share-fee-to-trait .dao-traits-v4.share-fee-to-trait)

(define-constant err-router-preconditions  (err u200))
(define-constant err-router-postconditions (err u201))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; add-liquidity
(define-read-only
  (add-liquidity-calc
    (id           uint)
    (amt0-desired uint)
    (amt1-desired uint)
    (amt0-min     uint)
    (amt1-min     uint))
  (let ((pool (contract-call? .univ2-core do-get-pool id))
        (r0   (get reserve0 pool))
        (r1   (get reserve1 pool)))
    (if (and (is-eq r0 u0) (is-eq r1 u0))
        (ok {amt0: amt0-desired, amt1: amt1-desired})
        (let ((amt1-optimal (try! (contract-call? .univ2-library quote amt0-desired r0 r1)))
              (amt0-optimal (try! (contract-call? .univ2-library quote amt1-desired r1 r0))) )
            ;; Note we do not use optimal if > desired.
            (if (<= amt1-optimal amt1-desired)
                (begin
                  (asserts! (>= amt1-optimal amt1-min) err-router-preconditions)
                  (ok {amt0: amt0-desired, amt1: amt1-optimal}))
                (begin
                  (asserts!
                    (and
                      (<= amt0-optimal amt0-desired)
                      (>= amt0-optimal amt0-min))
                    err-router-preconditions)
                  (ok {amt0: amt0-optimal, amt1: amt1-desired})) )) )))

(define-public
  (add-liquidity
    (id uint)
    (token0       <ft-trait>)
    (token1       <ft-trait>)
    (lp-token     <ft-plus-trait>)
    (amt0-desired uint)
    (amt1-desired uint)
    (amt0-min     uint)
    (amt1-min     uint))

  (let ((amts (try! (add-liquidity-calc
                id amt0-desired amt1-desired amt0-min amt1-min))))

    (asserts!
     (and (<= amt0-min amt0-desired)
          (<= amt1-min amt1-desired)
          (>= amt0-min u0)
          (>= amt1-min u0)
          (>= amt0-desired u0)
          (>= amt1-desired u0))
     err-router-preconditions)

    (contract-call? .univ2-core mint
      id
      token0
      token1
      lp-token
      (get amt0 amts)
      (get amt1 amts)) ))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; remove-liquidity
(define-public
  (remove-liquidity
    (id        uint)
    (token0    <ft-trait>)
    (token1    <ft-trait>)
    (lp-token  <ft-plus-trait>)
    (liquidity uint)
    (amt0-min  uint)
    (amt1-min  uint))

  (let ((event (try! (contract-call? .univ2-core burn
                  id token0 token1 lp-token liquidity))))

    (asserts!
      (and (>= (get amt0 event) amt0-min)
           (>= (get amt1 event) amt1-min))
      err-router-postconditions)

    (ok event) ))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; swap
(define-public
  (swap-exact-tokens-for-tokens
    (id             uint)
    (token0         <ft-trait>)
    (token1         <ft-trait>)
    (token-in       <ft-trait>)
    (token-out      <ft-trait>)
    (share-fee-to   <share-fee-to-trait>)
    (amt-in      uint)
    (amt-out-min uint))

  (let ((pool      (contract-call? .univ2-core do-get-pool id))
        (is-token0 (is-eq (contract-of token0) (contract-of token-in)))
        (amt-out   (try! (contract-call? .univ2-library get-amount-out
          amt-in
          (if is-token0 (get reserve0 pool) (get reserve1 pool))
          (if is-token0 (get reserve1 pool) (get reserve0 pool))
          (get swap-fee pool) )))
       (event      (try! (contract-call? .univ2-core swap
          id
          token-in
          token-out
          share-fee-to
          amt-in
          amt-out))) )

    (asserts!
     (and (is-eq (get token0 pool) (contract-of token0))
          (is-eq (get token1 pool) (contract-of token1))
          (> amt-in      u0)
          (> amt-out-min u0) )
     err-router-preconditions)

    (asserts!
      (and (>= (get amt-out event) amt-out-min))
      err-router-postconditions)

    (ok event) ))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define-public
  (swap-tokens-for-exact-tokens
    (id           uint)
    (token0       <ft-trait>)
    (token1       <ft-trait>)
    (token-in     <ft-trait>)
    (token-out    <ft-trait>)
    (share-fee-to <share-fee-to-trait>)
    (amt-in-max   uint)
    (amt-out      uint))

  (let ((pool      (contract-call? .univ2-core do-get-pool id))
        (is-token0 (is-eq (contract-of token0) (contract-of token-in)))
        (amt-in    (try! (contract-call? .univ2-library get-amount-in
          amt-out
          (if is-token0 (get reserve0 pool) (get reserve1 pool))
          (if is-token0 (get reserve1 pool) (get reserve0 pool))
          (get swap-fee pool) )))
        (event     (try! (contract-call? .univ2-core swap
          id
          token-in
          token-out
          share-fee-to
          amt-in
          amt-out))) )

  (asserts!
   (and (is-eq (get token0 pool) (contract-of token0))
        (is-eq (get token1 pool) (contract-of token1))
        (> amt-in-max u0)
        (> amt-out    u0) )
   err-router-preconditions)

  (asserts!
    (and (<= (get amt-in event) amt-in-max))
    err-router-postconditions)

  (ok event) ))

;;; eof

Functions (5)

FunctionAccessArgs
add-liquidity-calcread-onlyid: uint, amt0-desired: uint, amt1-desired: uint, amt0-min: uint, amt1-min: uint
add-liquiditypublicid: uint, token0: <ft-trait>, token1: <ft-trait>, lp-token: <ft-plus-trait>, amt0-desired: uint, amt1-desired: uint, amt0-min: uint, amt1-min: uint
remove-liquiditypublicid: uint, token0: <ft-trait>, token1: <ft-trait>, lp-token: <ft-plus-trait>, liquidity: uint, amt0-min: uint, amt1-min: uint
swap-exact-tokens-for-tokenspublicid: uint, token0: <ft-trait>, token1: <ft-trait>, token-in: <ft-trait>, token-out: <ft-trait>, share-fee-to: <share-fee-to-trait>, amt-in: uint, amt-out-min: uint
swap-tokens-for-exact-tokenspublicid: uint, token0: <ft-trait>, token1: <ft-trait>, token-in: <ft-trait>, token-out: <ft-trait>, share-fee-to: <share-fee-to-trait>, amt-in-max: uint, amt-out: uint