Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
234 changes: 234 additions & 0 deletions clarity/contracts/stake/arkadiko-stake-registry-v3-1.clar
Original file line number Diff line number Diff line change
@@ -0,0 +1,234 @@
;; @contract Stake Registry - Keep track of all staking pools
;; Users can stake, unstake and claim rewards from active pools.
;; DAO can activate a new pool or deactivate an existing one.
;; When a pool is deactivated, users can not stake but they can unstake.
;; @version 3.1

(use-trait ft-trait 'SP3FBR2AGK5H9QBDH3EEN6DF8EK8JY7RX8QJ5SVTE.sip-010-trait-ft-standard.sip-010-trait)
(use-trait stake-pool-trait .arkadiko-stake-pool-trait-v1.stake-pool-trait)
(use-trait stake-registry-trait .arkadiko-stake-registry-trait-v1.stake-registry-trait)
(impl-trait .arkadiko-stake-registry-trait-v1.stake-registry-trait)

;; Errors
(define-constant ERR-INVALID-POOL (err u19001))
(define-constant ERR-POOL-EXIST (err u19002))
(define-constant ERR-POOL-INACTIVE (err u19003))
(define-constant ERR-WRONG-REGISTRY (err u19004))
(define-constant ERR-NOT-AUTHORIZED u19401)

;; Variables
(define-data-var pool-count uint u0)

;; Pool maps
(define-map pools-data-map
{ pool: principal }
{
name: (string-ascii 256),
deactivated-block: uint,
deactivated-rewards-per-block: uint,
rewards-percentage: uint
}
)

;; Get pool info
(define-read-only (get-pool-data (pool principal))
(unwrap-panic (map-get? pools-data-map { pool: pool }))
)

;; Set pool info
(define-public (set-pool-data
(pool principal)
(name (string-ascii 256))
(deactivated-block uint)
(deactivated-rewards-per-block uint)
(rewards-percentage uint)
)
(begin
(asserts! (is-eq tx-sender (contract-call? .arkadiko-dao get-dao-owner)) (err ERR-NOT-AUTHORIZED))

(map-set pools-data-map
{ pool: pool }
{
name: name,
deactivated-block: deactivated-block,
deactivated-rewards-per-block: deactivated-rewards-per-block,
rewards-percentage: rewards-percentage
}
)
(ok true)
)
)

;; Get pool rewards per block
(define-read-only (get-rewards-per-block-for-pool (pool principal))
(let (
(total-staking-rewards u29362456)
(pool-percentage (get rewards-percentage (get-pool-data pool)))
(deactivated-block (get deactivated-block (get-pool-data pool)))
(deactivated-rewards-per-block (get deactivated-rewards-per-block (get-pool-data pool)))
)
(if (is-eq deactivated-block u0)
(ok (/ (* total-staking-rewards pool-percentage) u1000000))
(ok deactivated-rewards-per-block)
)
)
)

;; Get pool deactivated block
(define-read-only (get-pool-deactivated-block (pool principal))
(let (
(pool-info (unwrap! (map-get? pools-data-map { pool: pool }) ERR-POOL-EXIST))
(block (get deactivated-block pool-info))
)
(ok block)
)
)

;; @desc stake tokens
;; @param registry-trait; current stake registry, to be used by stake pool
;; @param pool-trait; pool to stake tokens in
;; @param token-trait; token to stake in pool
;; @param amount; amount of tokens to stake
;; @post uint; returns amount of staked tokens
(define-public (stake (registry-trait <stake-registry-trait>) (pool-trait <stake-pool-trait>) (token-trait <ft-trait>) (amount uint))
(begin
(let (
(pool (contract-of pool-trait))
(pool-info (unwrap! (map-get? pools-data-map { pool: pool }) ERR-POOL-EXIST))
)
(asserts! (is-eq (as-contract tx-sender) (contract-of registry-trait)) ERR-WRONG-REGISTRY)
(asserts! (is-eq (get deactivated-block pool-info) u0) ERR-POOL-INACTIVE)

(print {
type: "pool",
action: "stake",
data: { registry: registry-trait, pool: pool-trait, token: token-trait, amount: amount, owner: tx-sender }
})
(contract-call? pool-trait stake registry-trait token-trait tx-sender amount)
)
)
)

;; @desc unstake tokens
;; @param registry-trait; current stake registry, to be used by pool
;; @param pool-trait; pool to unstake tokens from
;; @param token-trait; token to unstake from pool
;; @param amount; amount of tokens to unstake
;; @post uint; returns amount of unstaked tokens
(define-public (unstake (registry-trait <stake-registry-trait>) (pool-trait <stake-pool-trait>) (token-trait <ft-trait>) (amount uint))
(begin
(let (
(pool (contract-of pool-trait))
(pool-info (unwrap! (map-get? pools-data-map { pool: pool }) ERR-POOL-EXIST))
)
(asserts! (is-eq (as-contract tx-sender) (contract-of registry-trait)) ERR-WRONG-REGISTRY)

(print {
type: "pool",
action: "unstake",
data: { registry: registry-trait, pool: pool-trait, token: token-trait, amount: amount, owner: tx-sender }
})
(contract-call? pool-trait unstake registry-trait token-trait tx-sender amount)
)
)
)

;; @desc get amount of pending DIKO rewards for pool
;; @param registry-trait; current stake registry, to be used by pool
;; @param pool-trait; pool to get pending rewards from
;; @post uint; returns amount of pending rewards
(define-public (get-pending-rewards (registry-trait <stake-registry-trait>) (pool-trait <stake-pool-trait>))
(begin
(let (
(pool (contract-of pool-trait))
(pool-info (unwrap! (map-get? pools-data-map { pool: pool }) ERR-POOL-EXIST))
)
(asserts! (is-eq (as-contract tx-sender) (contract-of registry-trait)) ERR-WRONG-REGISTRY)
(contract-call? pool-trait get-pending-rewards registry-trait tx-sender)
)
)
)

;; @desc claim pending DIKO rewards for pool
;; @param registry-trait; current stake registry, to be used by pool
;; @param pool-trait; pool to claim rewards on
;; @post uint; returns amount of claimed rewards
(define-public (claim-pending-rewards (registry-trait <stake-registry-trait>) (pool-trait <stake-pool-trait>))
(begin
(asserts! (is-eq (as-contract tx-sender) (contract-of registry-trait)) ERR-WRONG-REGISTRY)
(contract-call? pool-trait claim-pending-rewards registry-trait tx-sender)
)
)

;; @desc claim pending DIKO rewards for pool and immediately stake in DIKO pool
;; @param registry-trait; current stake registry, to be used by pool
;; @param pool-trait; pool to claim rewards on
;; @param diko-pool-trait; DIKO pool to stake rewards
;; @param diko-token-trait; DIKO token contract
;; @post uint; returns amount of claimed/staked rewards
(define-public (stake-pending-rewards
(registry-trait <stake-registry-trait>)
(pool-trait <stake-pool-trait>)
(diko-pool-trait <stake-pool-trait>)
(diko-token-trait <ft-trait>)
)
(let (
(claimed-rewards (unwrap-panic (contract-call? pool-trait claim-pending-rewards registry-trait tx-sender)))
)
(asserts! (is-eq (as-contract tx-sender) (contract-of registry-trait)) ERR-WRONG-REGISTRY)

(print {
type: "pool",
action: "stake-pending-rewards",
data: { registry: registry-trait, pool: pool-trait, owner: tx-sender }
})
(contract-call? diko-pool-trait stake registry-trait diko-token-trait tx-sender claimed-rewards)
)
)

;; ---------------------------------------------------------
;; Contract initialisation
;; ---------------------------------------------------------

(begin
;; DIKO pool
(map-set pools-data-map
{ pool: 'SP2C2YFP12AJZB4MABJBAJ55XECVS7E4PMMZ89YZR.arkadiko-stake-pool-diko-v2-1 }
{
name: "DIKO",
deactivated-block: u0,
deactivated-rewards-per-block: u0,
rewards-percentage: u160000 ;; 16%
}
)
;; DIKO-USDA LP
(map-set pools-data-map
{ pool: 'SP2C2YFP12AJZB4MABJBAJ55XECVS7E4PMMZ89YZR.arkadiko-stake-pool-diko-usda-v1-1 }
{
name: "DIKO-USDA LP",
deactivated-block: u0,
deactivated-rewards-per-block: u0,
rewards-percentage: u190000 ;; 19%
}
)
;; wSTX-USDA LP
(map-set pools-data-map
{ pool: 'SP2C2YFP12AJZB4MABJBAJ55XECVS7E4PMMZ89YZR.arkadiko-stake-pool-wstx-usda-v1-1 }
{
name: "wSTX-USDA LP",
deactivated-block: u0,
deactivated-rewards-per-block: u0,
rewards-percentage: u310000 ;; 31%
}
)
;; wSTX-DIKO LP
(map-set pools-data-map
{ pool: 'SP2C2YFP12AJZB4MABJBAJ55XECVS7E4PMMZ89YZR.arkadiko-stake-pool-wstx-diko-v1-1 }
{
name: "wSTX-DIKO LP",
deactivated-block: u0,
deactivated-rewards-per-block: u0,
rewards-percentage: u130000 ;; 13%
}
)
)
4 changes: 2 additions & 2 deletions web/components/stake-diko-modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,10 @@ export const StakeDikoModal: React.FC<Props> = ({ showStakeModal, setShowStakeMo
{
stxAddress,
contractAddress,
contractName: 'arkadiko-stake-registry-v2-1',
contractName: 'arkadiko-stake-registry-v3-1',
functionName: 'stake',
functionArgs: [
Cl.contractPrincipal(contractAddress, 'arkadiko-stake-registry-v2-1'),
Cl.contractPrincipal(contractAddress, 'arkadiko-stake-registry-v3-1'),
Cl.contractPrincipal(contractAddress, 'arkadiko-stake-pool-diko-v2-1'),
Cl.contractPrincipal(contractAddress, 'arkadiko-token'),
amount,
Expand Down
6 changes: 3 additions & 3 deletions web/components/stake-lp-modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ export const StakeLpModal = ({
contractName,
functionName: "stake",
functionArgs: [
Cl.contractPrincipal(contractAddress, 'arkadiko-stake-registry-v2-1'),
Cl.contractPrincipal(contractAddress, 'arkadiko-stake-registry-v3-1'),
Cl.contractPrincipal(assetContractAddress, tokenContract),
amount,
],
Expand All @@ -124,10 +124,10 @@ export const StakeLpModal = ({
{
stxAddress: stxAddress,
contractAddress: contractAddress,
contractName: "arkadiko-stake-registry-v2-1",
contractName: "arkadiko-stake-registry-v3-1",
functionName: "stake",
functionArgs: [
Cl.contractPrincipal(contractAddress, 'arkadiko-stake-registry-v2-1'),
Cl.contractPrincipal(contractAddress, 'arkadiko-stake-registry-v3-1'),
Cl.contractPrincipal(contractAddress, contractName),
Cl.contractPrincipal(assetContractAddress, tokenContract),
amount,
Expand Down
Loading
Loading