Source Code

;; SPDX-License-Identifier: BUSL-1.1

;; This contract acts as a helper for self-service farming pool setup.
;; It allows pool owners (or the DAO) to register a pool for dual-farming rewards
;; in a permissionless way, provided they meet certain requirements.

(use-trait ft-trait 'SP102V8P0F7JX67ARQ77WEA3D3CFB5XW39REDT0AM.trait-sip-010.sip-010-trait)

;; Error codes for various failure conditions
(define-constant err-not-authorised (err u1000))
(define-constant err-token-not-approved (err u1001))
(define-constant err-total-cycles (err u1002))
(define-constant err-rewards-per-cycle (err u1003))

;; ========== Read-only calls ==========

;; Checks if the sender is the DAO or an approved extension
(define-read-only (is-dao-or-extension)
    (ok (asserts! (or (is-eq tx-sender 'SP102V8P0F7JX67ARQ77WEA3D3CFB5XW39REDT0AM.executor-dao)
                      (contract-call? 'SP102V8P0F7JX67ARQ77WEA3D3CFB5XW39REDT0AM.executor-dao is-extension contract-caller))
                  err-not-authorised)))

;; ========== Public calls ==========

;; Allows a pool owner (or DAO) to request a new dual-farming campaign for their pool.
;; - token-x, token-y: The pool's token pair
;; - factor: The pool's factor (for AMM math)
;; - rewards-token-trait: The reward token contract trait
;; - total-rewards-in-fixed: Total reward tokens to distribute
;; - total-cycles: Over how many cycles to distribute rewards
(define-public (request (token-x principal) (token-y principal) (factor uint) (rewards-token-trait <ft-trait>) (total-rewards-in-fixed uint) (total-cycles uint))
    (let (
        ;; Get pool details from the AMM contract
        (pool-details (try! (contract-call? 'SP102V8P0F7JX67ARQ77WEA3D3CFB5XW39REDT0AM.amm-pool-v2-01 get-pool-details token-x token-y factor)))
        ;; Get the current reward cycle from the staking contract
        (current-cycle (unwrap-panic (contract-call? 'SP102V8P0F7JX67ARQ77WEA3D3CFB5XW39REDT0AM.alex-staking-v2 get-reward-cycle tenure-height)))
        ;; Calculate rewards per cycle
        (rewards-per-cycle (/ total-rewards-in-fixed total-cycles))
        ;; Check if the pool is already registered for dual-farming
        (user-nonce (contract-call? 'SP102V8P0F7JX67ARQ77WEA3D3CFB5XW39REDT0AM.alex-farming get-registered-users-nonce-or-default 'SP102V8P0F7JX67ARQ77WEA3D3CFB5XW39REDT0AM.token-amm-pool-v2-01 (get pool-id pool-details))))
        ;; Only the pool owner or DAO/extension can call this
        (asserts! (or (is-eq tx-sender (get pool-owner pool-details)) (is-ok (is-dao-or-extension))) err-not-authorised)
        ;; The reward token must be approved in the vault
        (asserts! (< u0 (contract-call? 'SP102V8P0F7JX67ARQ77WEA3D3CFB5XW39REDT0AM.amm-vault-v2-01 get-reserve (contract-of rewards-token-trait))) err-token-not-approved)
        ;; Must have at least one cycle
        (asserts! (< u0 total-cycles) err-total-cycles)
        ;; Must have a positive reward per cycle
        (asserts! (< u0 rewards-per-cycle) err-rewards-per-cycle)
        
        ;; If the pool is not registered, add it to the farming contract
        (and (is-eq user-nonce u0)
             (as-contract (try! (contract-call? 'SP102V8P0F7JX67ARQ77WEA3D3CFB5XW39REDT0AM.alex-farming add-token
                                                'SP102V8P0F7JX67ARQ77WEA3D3CFB5XW39REDT0AM.token-amm-pool-v2-01
                                                (get pool-id pool-details)))))
        ;; Set the activation block for the pool in the farming contract
        (as-contract (try! (contract-call? 'SP102V8P0F7JX67ARQ77WEA3D3CFB5XW39REDT0AM.alex-farming set-activation-block
                                           'SP102V8P0F7JX67ARQ77WEA3D3CFB5XW39REDT0AM.token-amm-pool-v2-01
                                           (get pool-id pool-details)
                                           u46601)))
        ;; Set the apower multiplier (default 0)
        (as-contract (try! (contract-call? 'SP102V8P0F7JX67ARQ77WEA3D3CFB5XW39REDT0AM.alex-farming set-apower-multiplier-in-fixed
                                           'SP102V8P0F7JX67ARQ77WEA3D3CFB5XW39REDT0AM.token-amm-pool-v2-01
                                           (get pool-id pool-details)
                                           u0)))
        ;; Set the coinbase amounts (default values)
        (as-contract (try! (contract-call? 'SP102V8P0F7JX67ARQ77WEA3D3CFB5XW39REDT0AM.alex-farming set-coinbase-amount
                                           'SP102V8P0F7JX67ARQ77WEA3D3CFB5XW39REDT0AM.token-amm-pool-v2-01
                                           (get pool-id pool-details)
                                           u100000000 u100000000 u100000000 u100000000 u100000000)))
        ;; Register the reward token and schedule in the dual-farming contract
        (as-contract (try! (contract-call? 'SP102V8P0F7JX67ARQ77WEA3D3CFB5XW39REDT0AM.dual-farming add-token
                                           'SP102V8P0F7JX67ARQ77WEA3D3CFB5XW39REDT0AM.token-amm-pool-v2-01
                                           (get pool-id pool-details)
                                           (contract-of rewards-token-trait)
                                           rewards-per-cycle
                                           (+ current-cycle u1)
                                           (+ current-cycle total-cycles))))
        ;; Transfer the total reward tokens from the sender to the dual-farming contract
        (try! (contract-call? rewards-token-trait transfer-fixed total-rewards-in-fixed tx-sender 'SP102V8P0F7JX67ARQ77WEA3D3CFB5XW39REDT0AM.dual-farming none))
        ;; Log the request
        (print { notification: "request", payload: { start-cycle: (+ current-cycle u1), end-cycle: (+ current-cycle total-cycles), rewards-per-cycle: rewards-per-cycle } })
        (ok true)))

;; ========== Privileged and Governance calls ==========

;; (none in this contract)

;; ========== Private calls ==========

Functions (2)

FunctionAccessArgs
is-dao-or-extensionread-only
requestpublictoken-x: principal, token-y: principal, factor: uint, rewards-token-trait: <ft-trait>, total-rewards-in-fixed: uint, total-cycles: uint