endpoint::burn; clarinet_manager

This commit is contained in:
fiftyeightandeight
2024-01-18 17:25:42 +08:00
parent c23f644365
commit 9364df5c5b
8 changed files with 162 additions and 18 deletions

1
.gitignore vendored
View File

@@ -11,3 +11,4 @@ coverage
*.info *.info
costs-reports.json costs-reports.json
node_modules node_modules
contracts_modules

10
Clarinet.json Normal file
View File

@@ -0,0 +1,10 @@
{
"name": "btc-bridge",
"dependencies": {
"alex_v1": {
"commit": "dev",
"git": "https://github.com/alexgo-io/alex-v1.git",
"contracts_path": "clarity/contracts"
}
}
}

View File

@@ -9,11 +9,11 @@ cache_dir = "./.cache"
[[project.requirements]] [[project.requirements]]
contract_id = "SP21YTSM60CAY6D011EZVEVNKXVW8FVZE198XEFFP.pox-fast-pool-v2" contract_id = "SP21YTSM60CAY6D011EZVEVNKXVW8FVZE198XEFFP.pox-fast-pool-v2"
[[project.requirements]] [contracts.trait-sip-010]
contract_id = "SP3FBR2AGK5H9QBDH3EEN6DF8EK8JY7RX8QJ5SVTE.sip-010-trait-ft-standard" path = "contracts_modules/alex_v1/traits/trait-sip-010.clar"
[[project.requirements]] [contracts.token-wstx]
contract_id = "SP3K8BC0PPEVCV7NZ6QSRWPQ2JE9E5B6N3PA0KBR9.token-wstx" path = "contracts_modules/alex_v1/wrapped-token/token-wstx.clar"
[contracts.lqstx-mint-endpoint] [contracts.lqstx-mint-endpoint]
path = "contracts/lqstx-mint-endpoint.clar" path = "contracts/lqstx-mint-endpoint.clar"

View File

@@ -2,7 +2,7 @@
;; lqstx-mint-endpoint ;; lqstx-mint-endpoint
;; ;;
(use-trait sip010-trait 'SP3FBR2AGK5H9QBDH3EEN6DF8EK8JY7RX8QJ5SVTE.sip-010-trait-ft-standard.sip-010-trait) (use-trait sip010-trait .trait-sip-010.sip-010-trait)
(define-constant ERR-NOT-AUTHORIZED (err u1000)) (define-constant ERR-NOT-AUTHORIZED (err u1000))
(define-constant ERR-PAUSED (err u1001)) (define-constant ERR-PAUSED (err u1001))
@@ -36,6 +36,9 @@
(define-read-only (get-mint-request-or-fail (request-id uint)) (define-read-only (get-mint-request-or-fail (request-id uint))
(contract-call? .lqstx-mint-registry get-mint-request-or-fail request-id)) (contract-call? .lqstx-mint-registry get-mint-request-or-fail request-id))
(define-read-only (get-burn-request-or-fail (request-id uint))
(contract-call? .lqstx-mint-registry get-burn-request-or-fail request-id))
(define-read-only (get-rewards-paid-upto) (define-read-only (get-rewards-paid-upto)
(contract-call? .lqstx-mint-registry get-rewards-paid-upto)) (contract-call? .lqstx-mint-registry get-rewards-paid-upto))
@@ -44,11 +47,13 @@
(request-details (try! (contract-call? .lqstx-mint-registry get-mint-request-or-fail request-id)))) (request-details (try! (contract-call? .lqstx-mint-registry get-mint-request-or-fail request-id))))
(ok (asserts! (>= (get-rewards-paid-upto) (get requested-at request-details)) ERR-REQUEST-PENDING)))) (ok (asserts! (>= (get-rewards-paid-upto) (get requested-at request-details)) ERR-REQUEST-PENDING))))
;; @dev it favours smaller amounts as we do not allow partial burn
(define-read-only (validate-burn-request (request-id uint)) (define-read-only (validate-burn-request (request-id uint))
(let ( (let (
(request-details (try! (contract-call? .lqstx-mint-registry get-burn-request-or-fail request-id))) (request-details (try! (contract-call? .lqstx-mint-registry get-burn-request-or-fail request-id)))
(balance (stx-account))) (vaulted-amount (try! (contract-call? .token-wlqstx convert-to-tokens (get amount request-details))))
(ok (asserts! (>= (get-rewards-paid-upto) (get requested-at request-details)) ERR-REQUEST-PENDING)))) (balance (stx-account .lqstx-mint-registry)))
(ok (asserts! (>= (get unlocked balance) vaulted-amount) ERR-REQUEST-PENDING))))
;; governance calls ;; governance calls
@@ -72,12 +77,12 @@
(try! (is-paused-or-fail)) (try! (is-paused-or-fail))
(try! (contract-call? 'SP3K8BC0PPEVCV7NZ6QSRWPQ2JE9E5B6N3PA0KBR9.token-wstx transfer-fixed amount tx-sender .lqstx-mint-registry none)) (try! (contract-call? 'SP3K8BC0PPEVCV7NZ6QSRWPQ2JE9E5B6N3PA0KBR9.token-wstx transfer-fixed amount tx-sender .lqstx-mint-registry none))
(print { type: "mint-request", id: request-id, details: request-details}) (print { type: "mint-request", id: request-id, details: request-details})
(ok true))) (ok request-id)))
(define-public (finalize-mint (request-id uint)) (define-public (finalize-mint (request-id uint))
(let ( (let (
(sender tx-sender)
(request-details (try! (get-mint-request-or-fail request-id)))) (request-details (try! (get-mint-request-or-fail request-id))))
(try! (is-paused-or-fail))
(try! (validate-mint-request request-id)) (try! (validate-mint-request request-id))
(try! (contract-call? .token-lqstx mint-fixed (get amount request-details) (get requested-by request-details))) (try! (contract-call? .token-lqstx mint-fixed (get amount request-details) (get requested-by request-details)))
(as-contract (contract-call? .lqstx-mint-registry set-mint-request request-id (merge request-details { status: (get-finalized) }))))) (as-contract (contract-call? .lqstx-mint-registry set-mint-request request-id (merge request-details { status: (get-finalized) })))))
@@ -87,16 +92,26 @@
(define-public (request-burn (amount uint)) (define-public (request-burn (amount uint))
(let ( (let (
;; @dev requested-at not used for burn
(cycle (contract-call? 'SP000000000000000000002Q6VF78.pox-3 current-pox-reward-cycle)) (cycle (contract-call? 'SP000000000000000000002Q6VF78.pox-3 current-pox-reward-cycle))
(request-details { requested-by: tx-sender, amount: amount, requested-at: cycle, status: (get-pending) }) (request-details { requested-by: tx-sender, amount: amount, requested-at: cycle, status: (get-pending) })
(request-id (as-contract (try! (contract-call? .lqstx-mint-registry set-burn-request u0 request-details))))) (request-id (as-contract (try! (contract-call? .lqstx-mint-registry set-burn-request u0 request-details)))))
(try! (is-paused-or-fail)) (try! (is-paused-or-fail))
(try! (contract-call? .token-lqstx transfer-fixed amount tx-sender .lqstx-mint-registry none)) (try! (contract-call? .token-wlqstx mint-fixed amount tx-sender))
(print { type: "burn-request", id: request-id, details: request-details }) (try! (contract-call? .token-wlqstx transfer-fixed amount tx-sender .lqstx-mint-registry none))
(ok true))) (print { type: "burn-request", id: request-id, details: request-details })
(ok request-id)))
(define-public (finalize-burn (request-id uint)) (define-public (finalize-burn (request-id uint))
(ok true)) (let (
(request-details (try! (get-burn-request-or-fail request-id)))
(transfer-wlqstx (as-contract (try! (contract-call? .lqstx-mint-registry transfer-fixed (get amount request-details) tx-sender .token-wlqstx))))
(vaulted-amount (as-contract (try! (contract-call? .token-wlqstx burn-fixed (get amount request-details) tx-sender)))))
(try! (is-paused-or-fail))
(try! (validate-burn-request request-id))
(as-contract (try! (contract-call? .token-lqstx burn-fixed vaulted-amount tx-sender)))
(as-contract (try! (contract-call? .lqstx-mint-registry transfer-fixed vaulted-amount (get requested-by request-details) .token-wstx)))
(as-contract (contract-call? .lqstx-mint-registry set-burn-request request-id (merge request-details { status: (get-finalized) })))))
(define-public (revoke-burn (request-id uint)) (define-public (revoke-burn (request-id uint))
(ok true)) (ok true))

View File

@@ -2,7 +2,7 @@
;; lqstx-mint-registry ;; lqstx-mint-registry
;; ;;
(use-trait sip010-trait 'SP3FBR2AGK5H9QBDH3EEN6DF8EK8JY7RX8QJ5SVTE.sip-010-trait-ft-standard.sip-010-trait) (use-trait sip010-trait .trait-sip-010.sip-010-trait)
(define-constant ERR-NOT-AUTHORIZED (err u1000)) (define-constant ERR-NOT-AUTHORIZED (err u1000))
(define-constant ERR-UNKNOWN-REQUEST-ID (err u1008)) (define-constant ERR-UNKNOWN-REQUEST-ID (err u1008))
@@ -88,10 +88,10 @@
(map-set burn-requests id details) (map-set burn-requests id details)
(ok id))) (ok id)))
(define-public (transfer-fixed (amount uint) (recipient principal)) (define-public (transfer-fixed (amount uint) (recipient principal) (token-trait <sip010-trait>))
(begin (begin
(try! (is-approved-operator)) (try! (is-approved-operator))
(as-contract (contract-call? 'SP3K8BC0PPEVCV7NZ6QSRWPQ2JE9E5B6N3PA0KBR9.token-wstx transfer-fixed amount tx-sender recipient none)))) (as-contract (contract-call? token-trait transfer-fixed amount tx-sender recipient none))))
;; @dev other pools can be added by upgrading registry ;; @dev other pools can be added by upgrading registry
(define-public (delegate-stx (amount uint)) (define-public (delegate-stx (amount uint))

View File

@@ -78,7 +78,8 @@
) )
(asserts! (is-eq sender tx-sender) ERR-NOT-AUTHORIZED) (asserts! (is-eq sender tx-sender) ERR-NOT-AUTHORIZED)
(try! (ft-burn? wlqstx (fixed-to-decimals amount) sender)) (try! (ft-burn? wlqstx (fixed-to-decimals amount) sender))
(as-contract (contract-call? .token-lqstx transfer-fixed vaulted-amount tx-sender sender none)))) (as-contract (try! (contract-call? .token-lqstx transfer-fixed vaulted-amount tx-sender sender none)))
(ok vaulted-amount)))
;; read-only functions ;; read-only functions

View File

@@ -5,6 +5,7 @@
"description": "Run unit tests on this project.", "description": "Run unit tests on this project.",
"private": true, "private": true,
"scripts": { "scripts": {
"setup:clarity": "./scripts/clarinet_manager.sh clean && ./scripts/clarinet_manager.sh install",
"test": "vitest run", "test": "vitest run",
"test:report": "vitest run -- --coverage --costs", "test:report": "vitest run -- --coverage --costs",
"test:watch": "chokidar \"tests/**/*.ts\" \"contracts/**/*.clar\" -c \"npm run test:report\"" "test:watch": "chokidar \"tests/**/*.ts\" \"contracts/**/*.clar\" -c \"npm run test:report\""

116
scripts/clarinet_manager.sh Executable file
View File

@@ -0,0 +1,116 @@
#!/usr/bin/env bash
set -euo pipefail
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
ROOT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && cd .. && pwd )"
TMP_GIT_DIR="$ROOT/.git_tmp_repos"
CONTRACTS_MODULE_PATH="contracts_modules"
pre_check() {
echo "Installing from Clarinet.json..."
# check if file not exists
if [ ! -f "$DIR/../Clarinet.json" ]; then
echo "Clarity.json not found. abort..."
exit 1
fi
# check if command jq is installed, if not, install jq
if ! [ -x "$(command -v jq)" ]; then
echo "jq not installed. Install it before continue. (brew install jq)..."
exit 1
fi
}
install_project() {
project_name=${1//\"/}
echo "Installing project...$project_name"
commit=$(cat Clarinet.json | jq -cr ".dependencies.$project_name.commit")
git_repo=$(cat Clarinet.json | jq -cr ".dependencies.$project_name.git")
contracts_path=$(cat Clarinet.json | jq -cr ".dependencies.$project_name.contracts_path")
echo "Installing from $git_repo, commit $commit, to $project_name"
mkdir -p "$TMP_GIT_DIR"/"$project_name"
echo git clone "$git_repo" "$TMP_GIT_DIR"/"$project_name"
git clone "$git_repo" "$TMP_GIT_DIR"/"$project_name"
pushd "$TMP_GIT_DIR"/"$project_name" > /dev/null
echo git checkout "$commit"
git checkout "$commit"
popd > /dev/null
mkdir -p "$ROOT/$CONTRACTS_MODULE_PATH"
rm -rf "$ROOT/$CONTRACTS_MODULE_PATH/${project_name:?}"
cp -r "$TMP_GIT_DIR"/"$project_name"/"$contracts_path" "$ROOT"/"$CONTRACTS_MODULE_PATH"/$project_name
echo "cleaning..."
rm -rf "$TMP_GIT_DIR"
echo "installed $project_name"
}
install() {
pre_check
pushd "$DIR"/.. > /dev/null
projects_str=$(cat Clarinet.json | jq -c ".dependencies | keys" | sed -e 's/\[//g' -e 's/\]//g' -e 's/\,/ /g')
projects=($projects_str)
for i in "${projects[@]}"; do
install_project $i
done
echo installed all projects: $projects
}
clean() {
rm -rf "$TMP_GIT_DIR"
rm -rf "$ROOT/${CONTRACTS_MODULE_PATH:?}"
}
update() {
project_name=$1
branch=$2
echo "Updating project...$project_name commit from branch head of [$branch]"
git_repo=$(cat Clarinet.json | jq -cr ".dependencies.$project_name.git")
contracts_path=$(cat Clarinet.json | jq -cr ".dependencies.$project_name.contracts_path")
echo "Installing from $git_repo, to $project_name"
mkdir -p "$TMP_GIT_DIR"/"$project_name"
echo git clone "$git_repo" "$TMP_GIT_DIR"/"$project_name"
git clone "$git_repo" "$TMP_GIT_DIR"/"$project_name"
pushd "$TMP_GIT_DIR"/"$project_name" > /dev/null
git checkout "$branch"
current_commit=$(git show -s --format=%H)
echo ------using commit------
git log --format=%B -n 1 $(git log -1 --pretty=format:"%h")
echo ------end commit------
popd > /dev/null
echo branch $branch has commit $current_commit
cat <<< $(jq ".dependencies.$project_name.commit=\"$current_commit\"" Clarinet.json) > Clarinet.json
echo "cleaning..."
rm -rf "$TMP_GIT_DIR"
echo "updated $project_name"
}
main() {
# check if command is valid
if [ "$1" == "install" ]; then
install
elif [ "$1" == "clean" ]; then
clean
elif [ "$1" == "update" ]; then
# check if project and branch are provided
if [ -z "${2:-}" ] || [ -z "${3:-}" ]; then
echo "Usage: clarinet_manager.sh update <project> <branch>"
exit 1
fi
update $2 $3
else
echo "Invalid command. Use: ./clarinet_manager.sh install | clean | update"
fi
}
main $@