Source Code

;; Launchpad Token Factory
;; Creates new SIP-010 compliant tokens for the launchpad
;; Clarity 4 compatible

;; Constants
(define-constant ERR-NOT-AUTHORIZED (err u100))
(define-constant ERR-ALREADY-EXISTS (err u101))
(define-constant ERR-INVALID-NAME (err u102))
(define-constant ERR-INVALID-SYMBOL (err u103))

;; Contract owner
(define-constant CONTRACT-OWNER tx-sender)

;; Data maps
(define-map tokens
  { token-id: uint }
  {
    name: (string-ascii 32),
    symbol: (string-ascii 10),
    creator: principal,
    bonding-curve: principal,
    created-at: uint,
    image-uri: (optional (string-utf8 256)),
    description: (optional (string-utf8 500)),
    is-graduated: bool
  }
)

(define-map token-by-symbol
  { symbol: (string-ascii 10) }
  { token-id: uint }
)

;; Data variables
(define-data-var next-token-id uint u1)
(define-data-var platform-fee-percent uint u100) ;; 1% = 100 basis points

;; Read-only functions
(define-read-only (get-token-info (token-id uint))
  (map-get? tokens { token-id: token-id })
)

(define-read-only (get-token-by-symbol (symbol (string-ascii 10)))
  (map-get? token-by-symbol { symbol: symbol })
)

(define-read-only (get-next-token-id)
  (var-get next-token-id)
)

(define-read-only (get-platform-fee)
  (var-get platform-fee-percent)
)

;; Public functions

;; Register a new token (called after bonding curve deploys the token)
(define-public (register-token 
  (name (string-ascii 32))
  (symbol (string-ascii 10))
  (bonding-curve principal)
  (image-uri (optional (string-utf8 256)))
  (description (optional (string-utf8 500))))
  (let
    (
      (token-id (var-get next-token-id))
      (caller tx-sender)
    )
    ;; Validate inputs
    (asserts! (> (len name) u0) ERR-INVALID-NAME)
    (asserts! (> (len symbol) u0) ERR-INVALID-SYMBOL)
    
    ;; Check symbol doesn't already exist
    (asserts! (is-none (map-get? token-by-symbol { symbol: symbol })) ERR-ALREADY-EXISTS)
    
    ;; Store token info
    (map-set tokens
      { token-id: token-id }
      {
        name: name,
        symbol: symbol,
        creator: caller,
        bonding-curve: bonding-curve,
        created-at: stacks-block-height,
        image-uri: image-uri,
        description: description,
        is-graduated: false
      }
    )
    
    ;; Store symbol -> token-id mapping
    (map-set token-by-symbol
      { symbol: symbol }
      { token-id: token-id }
    )
    
    ;; Increment token ID
    (var-set next-token-id (+ token-id u1))
    
    ;; Emit event via print
    (print {
      event: "token-created",
      token-id: token-id,
      name: name,
      symbol: symbol,
      creator: caller,
      bonding-curve: bonding-curve
    })
    
    (ok token-id)
  )
)

;; Mark token as graduated (migrated to ALEX DEX)
(define-public (set-graduated (token-id uint))
  (let
    (
      (token-info (unwrap! (map-get? tokens { token-id: token-id }) ERR-NOT-AUTHORIZED))
    )
    ;; Only bonding curve can mark as graduated
    (asserts! (is-eq tx-sender (get bonding-curve token-info)) ERR-NOT-AUTHORIZED)
    
    ;; Update token info
    (map-set tokens
      { token-id: token-id }
      (merge token-info { is-graduated: true })
    )
    
    ;; Emit graduation event
    (print {
      event: "token-graduated",
      token-id: token-id,
      symbol: (get symbol token-info)
    })
    
    (ok true)
  )
)

;; Admin function to update platform fee
(define-public (set-platform-fee (new-fee uint))
  (begin
    (asserts! (is-eq tx-sender CONTRACT-OWNER) ERR-NOT-AUTHORIZED)
    (asserts! (<= new-fee u1000) ERR-NOT-AUTHORIZED) ;; Max 10%
    (var-set platform-fee-percent new-fee)
    (ok true)
  )
)

Functions (7)

FunctionAccessArgs
get-token-inforead-onlytoken-id: uint
get-token-by-symbolread-onlysymbol: (string-ascii 10
get-next-token-idread-only
get-platform-feeread-only
register-tokenpublicname: (string-ascii 32
set-graduatedpublictoken-id: uint
set-platform-feepublicnew-fee: uint