Source Code

;; Title: ROCK-PEPE Liquidity Pool
;; Version: 1.0.0
;; Description:
;; Implementation of the standard trait interface for liquidity pools on the Stacks blockchain.
;; Provides automated market making functionality between two SIP-010 compliant tokens.
;; Implements SIP-010 fungible token standard for LP token compatibility.
;; Generated by Charisma Launchpad

;; 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_UNAUTHORIZED (err u403))
(define-constant ERR_INVALID_OPERATION (err u400))
(define-constant PRECISION u1000000)
(define-constant LP_REBATE u30000)

;; 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 LP token
(define-fungible-token ROCK-PEPE)
(define-data-var token-uri (optional (string-utf8 256)) none)

;; --- SIP010 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? ROCK-PEPE amount sender recipient))
    (match memo to-print (print to-print) 0x0000)
    (ok true)
  )
)

(define-read-only (get-name)
  (ok "ROCK-PEPE Liquidity Pool")
)

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

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

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

(define-read-only (get-total-supply)
  (ok (ft-get-supply ROCK-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)
      (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))
  (let (
    (sender tx-sender)
    (delta (get-swap-quote amount (some 0x00)))
  )
    ;; Transfer token A to pool
    (try! (contract-call? 'SP4M2C88EE8RQZPYTC4PZ88CE16YGP825EYF6KBQ.stacks-rock transfer amount sender CONTRACT none))
    ;; Transfer token B to sender
    (try! (as-contract
      (contract-call? 'SP1Z92MPDQEWZXW36VX71Q25HKF5K2EPCJ304F275.tokensoft-token-v4k68639zxz transfer (get dy delta) CONTRACT sender none)
    ))
    (print { op: "swap-a-to-b", sender: sender, amount: amount, delta: delta })
    (ok delta)
  )
)

(define-public (swap-b-to-a (amount uint))
  (let (
    (sender tx-sender)
    (delta (get-swap-quote amount (some 0x01)))
  )
    ;; 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? 'SP4M2C88EE8RQZPYTC4PZ88CE16YGP825EYF6KBQ.stacks-rock transfer (get dy delta) CONTRACT sender none)
    ))
    (print { op: "swap-b-to-a", sender: sender, amount: amount, delta: delta })
    (ok delta)
  )
)

(define-public (add-liquidity (amount uint))
  (let (
    (sender tx-sender)
    (delta (get-liquidity-quote amount))
  )
    (try! (contract-call? 'SP4M2C88EE8RQZPYTC4PZ88CE16YGP825EYF6KBQ.stacks-rock transfer (get dx delta) sender CONTRACT none))
    (try! (contract-call? 'SP1Z92MPDQEWZXW36VX71Q25HKF5K2EPCJ304F275.tokensoft-token-v4k68639zxz transfer (get dy delta) sender CONTRACT none))
    (try! (ft-mint? ROCK-PEPE (get dk delta) sender))
    (print { op: "add-liquidity", sender: sender, amount: amount, delta: delta })
    (ok delta)
  )
)

(define-public (remove-liquidity (amount uint))
  (let (
    (sender tx-sender)
    (delta (get-liquidity-quote amount))
  )
    (try! (ft-burn? ROCK-PEPE (get dk delta) sender))
    (try! (as-contract
      (contract-call? 'SP4M2C88EE8RQZPYTC4PZ88CE16YGP825EYF6KBQ.stacks-rock transfer (get dx delta) CONTRACT sender none)
    ))
    (try! (as-contract
      (contract-call? 'SP1Z92MPDQEWZXW36VX71Q25HKF5K2EPCJ304F275.tokensoft-token-v4k68639zxz transfer (get dy delta) CONTRACT sender none)
    ))
    (print { op: "remove-liquidity", sender: sender, amount: amount, delta: delta })
    (ok delta)
  )
)

;; --- 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? 'SP4M2C88EE8RQZPYTC4PZ88CE16YGP825EYF6KBQ.stacks-rock 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 ROCK-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 ROCK-PEPE))
  )
    {
      dx: (get a reserves),
      dy: (get b reserves),
      dk: supply
    }
))

;; --- Initialization ---
(begin
  ;; Set token URI
  (var-set token-uri (some u"https://metadata.charisma.rocks/api/v1/metadata/SP22KATK6MJF40987KB2KSZQ6E027HQ0CPP73C9Y.rock-pepe-v1"))
  
  ;; Add initial balanced liquidity (handles both token transfers at 1:1)
  (try! (add-liquidity u20000000))
  
  ;; Transfer additional token A to achieve desired ratio
  (try! (contract-call? 'SP4M2C88EE8RQZPYTC4PZ88CE16YGP825EYF6KBQ.stacks-rock transfer u1099980000000 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-a-to-bpublicamount: uint
swap-b-to-apublicamount: uint
add-liquiditypublicamount: uint
remove-liquiditypublicamount: uint
get-byteprivateopcode: (buff 16
get-reservesprivate
get-swap-quoteread-onlyamount: uint, opcode: (optional (buff 16
get-liquidity-quoteread-onlyamount: uint
get-reserves-quoteread-only