Source Code

;; Title: sBTC-PEPE lp-token
;; Notice how Bitcoin and its meme offspring are like the fingers and palm of the same hand 
;; - seemingly separate until they fold together. 
;; In this asymmetric dance between Bitcoin and PEPE, we glimpse the unspoken truth: the division was always an illusion.
;; Forked from Charisma. Generated by Faktory

;; Traits
(impl-trait 'SP2ZNGJ85ENDY6QRHQ5P2D4FXKGZWCKTB2T0Z55KS.charisma-traits-v1.sip010-ft-trait)
(impl-trait 'SP2ZNGJ85ENDY6QRHQ5P2D4FXKGZWCKTB2T0Z55KS.dexterity-traits-v0.liquidity-pool-trait)

;; Constants
(define-constant DEPLOYER tx-sender)
(define-constant CONTRACT (as-contract tx-sender))

(define-constant ERR_INVALID_OPERATION (err u400))
(define-constant ERR_UNAUTHORIZED (err u403))
(define-constant ERR_RESTRICTED_OPERATION (err u405))
(define-constant ERR_TOO_MUCH_SLIPPAGE (err u407))

(define-constant EXIT_TAX_INITIAL u69000) ;; 6.9% with precision factor
(define-constant EXIT_TAX_YEAR_ONE u42000) ;; 4.2% with precision factor
(define-constant EXIT_TAX_YEAR_TWO u21000) ;; 2.1% with precision factor
(define-constant YEAR_IN_BLOCKS u52560) ;; 144 blocks * 365 days
(define-constant TWO_YEARS_IN_BLOCKS u105120) ;; 2 * YEAR_IN_BLOCKS
(define-constant DEPLOYMENT-HEIGHT burn-block-height)

(define-constant AUTHORIZED_BUYER .pepe-styx)

(define-constant PRECISION u1000000)
(define-constant LP_REBATE u6900)

;; Opcodes
(define-constant OP_SWAP_A_TO_B 0x00) ;; Swap token A for B
(define-constant OP_SWAP_B_TO_A 0x01) ;; Swap token B for A
(define-constant OP_ADD_LIQUIDITY 0x02) ;; Add liquidity
(define-constant OP_REMOVE_LIQUIDITY 0x03) ;; Remove liquidity
(define-constant OP_LOOKUP_RESERVES 0x04) ;; Read pool reserves

(define-constant SAINT 'SP000000000000000000002Q6VF78)

;; Define LP token
(define-fungible-token sBTC-PEPE)
(define-data-var token-uri (optional (string-utf8 256)) none)

;; --- SIP10 Functions ---

(define-public (transfer
    (amount uint)
    (sender principal)
    (recipient principal)
    (memo (optional (buff 34)))
  )
  (begin
    (asserts! (is-eq tx-sender sender) ERR_UNAUTHORIZED)
    (try! (ft-transfer? sBTC-PEPE amount sender recipient))
    (match memo
      to-print (print to-print)
      0x0000
    )
    (print {
      type: "transfer-lp",
      sender: sender,
      recipient: recipient,
      amount: amount,
    })
    (ok true)
  )
)

(define-read-only (get-name)
  (ok "sBTC-PEPE lp-token")
)

(define-read-only (get-symbol)
  (ok "sBTC-PEPE")
)

(define-read-only (get-decimals)
  (ok u6)
)

(define-read-only (get-balance (who principal))
  (ok (ft-get-balance sBTC-PEPE who))
)

(define-read-only (get-total-supply)
  (ok (ft-get-supply sBTC-PEPE))
)

(define-read-only (get-token-uri)
  (ok (var-get token-uri))
)

(define-public (set-token-uri (uri (string-utf8 256)))
  (if (is-eq contract-caller DEPLOYER)
    (ok (var-set token-uri (some uri)))
    ERR_UNAUTHORIZED
  )
)

;; --- Core Functions ---

(define-public (execute
    (amount uint)
    (opcode (optional (buff 16)))
  )
  (let (
      (sender tx-sender)
      (operation (get-byte (default-to 0x00 opcode) u0))
    )
    (if (is-eq operation OP_SWAP_A_TO_B)
      (swap-a-to-b amount u0)
      (if (is-eq operation OP_SWAP_B_TO_A)
        (swap-b-to-a amount)
        (if (is-eq operation OP_ADD_LIQUIDITY)
          (add-liquidity amount)
          (if (is-eq operation OP_REMOVE_LIQUIDITY)
            (remove-liquidity amount)
            ERR_INVALID_OPERATION
          )
        )
      )
    )
  )
)

(define-read-only (quote
    (amount uint)
    (opcode (optional (buff 16)))
  )
  (let ((operation (get-byte (default-to 0x00 opcode) u0)))
    (if (is-eq operation OP_SWAP_A_TO_B)
      (ok (get-swap-quote amount (some 0x00)))
      (if (is-eq operation OP_SWAP_B_TO_A)
        (ok (get-swap-quote amount (some 0x01)))
        (if (is-eq operation OP_ADD_LIQUIDITY)
          (ok (get-liquidity-quote amount))
          (if (is-eq operation OP_REMOVE_LIQUIDITY)
            (ok (get-liquidity-quote amount))
            (if (is-eq operation OP_LOOKUP_RESERVES)
              (ok (get-reserves-quote))
              ERR_INVALID_OPERATION
            )
          )
        )
      )
    )
  )
)

;; --- Execute Functions ---

(define-public (swap-a-to-b
    (amount uint)
    (min-y-out uint)
  )
  (let (
      (sender tx-sender)
      (delta (get-swap-quote amount (some 0x00)))
      (dy-d (get dy delta))
    )
    (asserts! (>= dy-d min-y-out) ERR_TOO_MUCH_SLIPPAGE)
    (asserts! (is-eq contract-caller AUTHORIZED_BUYER) ERR_RESTRICTED_OPERATION)
    ;; Transfer token A to pool
    (try! (contract-call? 'SM3VDXK3WZZSA84XXFKAFAF15NNZX32CTSG82JFQ4.sbtc-token
      transfer amount sender CONTRACT none
    ))
    ;; Transfer token B to sender
    (try! (as-contract (contract-call?
      'SP1Z92MPDQEWZXW36VX71Q25HKF5K2EPCJ304F275.tokensoft-token-v4k68639zxz
      transfer dy-d CONTRACT sender none
    )))
    (print {
      type: "buy",
      sender: sender,
      token-in: "sbtc",
      amount-in: amount,
      token-out: "pepe",
      amount-out: dy-d,
    })
    (ok delta)
  )
)

(define-public (swap-b-to-a (amount uint))
  (let (
      (sender tx-sender)
      (delta (get-swap-quote amount (some 0x01)))
      (dy-d (get dy delta))
    )
    ;; Transfer token B to pool
    (try! (contract-call?
      'SP1Z92MPDQEWZXW36VX71Q25HKF5K2EPCJ304F275.tokensoft-token-v4k68639zxz
      transfer amount sender CONTRACT none
    ))
    ;; Transfer token A to sender
    (try! (as-contract (contract-call? 'SM3VDXK3WZZSA84XXFKAFAF15NNZX32CTSG82JFQ4.sbtc-token
      transfer dy-d CONTRACT sender none
    )))
    (print {
      type: "sell",
      sender: sender,
      token-in: "pepe",
      amount-in: amount,
      token-out: "sbtc",
      amount-out: dy-d,
    })
    (ok delta)
  )
)

(define-public (add-liquidity (amount uint))
  (let (
      (sender tx-sender)
      (delta (get-liquidity-quote amount))
      (dx-d (get dx delta))
      (dy-d (get dy delta))
      (dk-d (get dk delta))
    )
    (try! (contract-call? 'SM3VDXK3WZZSA84XXFKAFAF15NNZX32CTSG82JFQ4.sbtc-token
      transfer dx-d sender CONTRACT none
    ))
    (try! (contract-call?
      'SP1Z92MPDQEWZXW36VX71Q25HKF5K2EPCJ304F275.tokensoft-token-v4k68639zxz
      transfer dy-d sender CONTRACT none
    ))
    (try! (ft-mint? sBTC-PEPE dk-d sender))
    (print {
      type: "add-liquidity",
      sender: sender,
      sbtc-amount: dx-d,
      token-amount: dy-d,
      lp-tokens: dk-d,
    })
    (ok delta)
  )
)

(define-public (remove-liquidity (amount uint))
  (let (
      (sender tx-sender)
      (delta (get-liquidity-quote amount))
      (dx-d (get dx delta))
      (dy-d (get dy delta))
      (dk-d (get dk delta))
      (tax-rate (get-exit-tax-rate))
      (dx-user (/ (* dx-d (- PRECISION tax-rate)) PRECISION))
      (dy-user (/ (* dy-d (- PRECISION tax-rate)) PRECISION))
      (dk-user (/ (* dk-d (- PRECISION tax-rate)) PRECISION))
      (dk-burn (- dk-d dk-user))
    )
    (try! (ft-burn? sBTC-PEPE dk-user sender))
    (try! (ft-transfer? sBTC-PEPE dk-burn sender SAINT))
    (try! (as-contract (contract-call? 'SM3VDXK3WZZSA84XXFKAFAF15NNZX32CTSG82JFQ4.sbtc-token
      transfer dx-user CONTRACT sender none
    )))
    (try! (as-contract (contract-call?
      'SP1Z92MPDQEWZXW36VX71Q25HKF5K2EPCJ304F275.tokensoft-token-v4k68639zxz
      transfer dy-user CONTRACT sender none
    )))
    (print {
      type: "remove-liquidity",
      sender: sender,
      sbtc-amount: dx-user,
      token-amount: dy-user,
      lp-tokens: dk-user,
      tax-rate: tax-rate,
      dk-burn: dk-burn
    })
    (ok delta)
  )
)

(define-read-only (get-exit-tax-rate)
  (let (
      (blocks-since-deployment (- burn-block-height DEPLOYMENT-HEIGHT))
    )
    (if (>= blocks-since-deployment TWO_YEARS_IN_BLOCKS)
      EXIT_TAX_YEAR_TWO
      (if (>= blocks-since-deployment YEAR_IN_BLOCKS)
        EXIT_TAX_YEAR_ONE
        EXIT_TAX_INITIAL
      )
    )
  )
)

;; --- Helper Functions ---

(define-private (get-byte
    (opcode (buff 16))
    (position uint)
  )
  (default-to 0x00 (element-at? opcode position))
)

(define-private (get-reserves)
  {
    a: (unwrap-panic (contract-call? 'SM3VDXK3WZZSA84XXFKAFAF15NNZX32CTSG82JFQ4.sbtc-token
      get-balance CONTRACT
    )),
    b: (unwrap-panic (contract-call?
      'SP1Z92MPDQEWZXW36VX71Q25HKF5K2EPCJ304F275.tokensoft-token-v4k68639zxz
      get-balance CONTRACT
    )),
  }
)

;; --- Quote Functions ---

(define-read-only (get-swap-quote
    (amount uint)
    (opcode (optional (buff 16)))
  )
  (let (
      (reserves (get-reserves))
      (operation (get-byte (default-to 0x00 opcode) u0))
      (is-a-in (is-eq operation OP_SWAP_A_TO_B))
      (x (if is-a-in
        (get a reserves)
        (get b reserves)
      ))
      (y (if is-a-in
        (get b reserves)
        (get a reserves)
      ))
      (dx (/ (* amount (- PRECISION LP_REBATE)) PRECISION))
      (numerator (* dx y))
      (denominator (+ x dx))
      (dy (/ numerator denominator))
    )
    {
      dx: dx,
      dy: dy,
      dk: u0,
    }
  )
)

(define-read-only (get-liquidity-quote (amount uint))
  (let (
      (k (ft-get-supply sBTC-PEPE))
      (reserves (get-reserves))
    )
    {
      dx: (if (> k u0)
        (/ (* amount (get a reserves)) k)
        amount
      ),
      dy: (if (> k u0)
        (/ (* amount (get b reserves)) k)
        amount
      ),
      dk: amount,
    }
  )
)

(define-read-only (get-reserves-quote)
  (let (
      (reserves (get-reserves))
      (supply (ft-get-supply sBTC-PEPE))
    )
    {
      dx: (get a reserves),
      dy: (get b reserves),
      dk: supply,
    }
  )
)

;; --- Initialization ---
(begin
    ;; Add initial balanced liquidity (handles both token transfers at 1:1)
    (try! (add-liquidity u5407100))
    ;; Transfer additional token B to achieve desired ratio
    (try! (contract-call? 'SP1Z92MPDQEWZXW36VX71Q25HKF5K2EPCJ304F275.tokensoft-token-v4k68639zxz transfer u149994592900 tx-sender CONTRACT none))
)

Functions (19)

FunctionAccessArgs
transferpublicamount: uint, sender: principal, recipient: principal, memo: (optional (buff 34
get-nameread-only
get-symbolread-only
get-decimalsread-only
get-balanceread-onlywho: principal
get-total-supplyread-only
get-token-uriread-only
set-token-uripublicuri: (string-utf8 256
executepublicamount: uint, opcode: (optional (buff 16
quoteread-onlyamount: uint, opcode: (optional (buff 16
swap-b-to-apublicamount: uint
add-liquiditypublicamount: uint
remove-liquiditypublicamount: uint
get-exit-tax-rateread-only
get-byteprivateopcode: (buff 16
get-reservesprivate
get-swap-quoteread-onlyamount: uint, opcode: (optional (buff 16
get-liquidity-quoteread-onlyamount: uint
get-reserves-quoteread-only