From 82aeb782b8050cadc65b8d20ab9d19ef5abf65cd Mon Sep 17 00:00:00 2001 From: Bought <120880223+boughtbtc@users.noreply.github.com> Date: Mon, 26 Feb 2024 11:41:45 -0700 Subject: [PATCH] add lp-token-v2.clar contract and tests file --- Clarinet.toml | 5 ++ contracts/lp-token-v2.clar | 102 +++++++++++++++++++++++++++++++++++++ tests/lp-token-v2_test.ts | 67 ++++++++++++++++++++++++ 3 files changed, 174 insertions(+) create mode 100644 contracts/lp-token-v2.clar create mode 100644 tests/lp-token-v2_test.ts diff --git a/Clarinet.toml b/Clarinet.toml index 535143d..6097f94 100644 --- a/Clarinet.toml +++ b/Clarinet.toml @@ -10,6 +10,11 @@ path = 'contracts/lp-token.clar' clarity_version = 2 epoch = 2.1 +[contracts.lp-token-v2] +path = 'contracts/lp-token-v2.clar' +clarity_version = 2 +epoch = 2.1 + [contracts.lp-trait] path = 'contracts/lp-trait.clar' clarity_version = 2 diff --git a/contracts/lp-token-v2.clar b/contracts/lp-token-v2.clar new file mode 100644 index 0000000..27fd455 --- /dev/null +++ b/contracts/lp-token-v2.clar @@ -0,0 +1,102 @@ +;; usda-susdt-lp-token + +;;;;;;;;;;;;;;;;;;;;; SIP 010 ;;;;;;;;;;;;;;;;;;;;;; +;; (impl-trait .bitflow-sip-010.bitflow-lp-trait) +(impl-trait .sip-010-trait-ft-standard.sip-010-trait) +(impl-trait .lp-trait.lp-trait) + + +(define-fungible-token usda-susdt-lp) + + +(define-constant CONTRACT-OWNER 'ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM) +(define-constant ERR-UNAUTHORIZED-MINT (err u100)) +(define-constant ERR-NOT-AUTHORIZED (err u101)) + +;;vars +(define-data-var token-uri (string-utf8 256) u"") +(define-data-var approved-supply-controller principal 'ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM.stableswap) + + +;; --------------------------------------------------------- +;; SIP-10 Functions +;; --------------------------------------------------------- +(define-read-only (adheres-to-sip-010) + (ok true) +) + +(define-read-only (get-name) + (ok "USDA-sUSDT-LP") +) + +(define-read-only (get-symbol) + (ok "USDA-sUSDT-LP") +) + +(define-read-only (get-decimals) + (ok u0) +) + +(define-read-only (get-balance (account principal)) + (ok (ft-get-balance usda-susdt-lp account)) +) + +(define-read-only (get-total-supply) + (ok (ft-get-supply usda-susdt-lp)) +) + + +(define-read-only (get-token-uri) + (ok (some (var-get token-uri))) +) + +(define-public (set-token-uri (uri (string-utf8 256))) + (begin + (asserts! (is-eq tx-sender CONTRACT-OWNER) ERR-NOT-AUTHORIZED) + (ok (var-set token-uri uri)) + ) +) + +(define-public (transfer (amount uint) (sender principal) (recipient principal) (memo (optional (buff 34)))) + (begin + (asserts! (is-eq tx-sender sender) ERR-NOT-AUTHORIZED) + + (match (ft-transfer? usda-susdt-lp amount sender recipient) + response (begin + (print memo) + (ok response) + ) + error (err error) + ) + ) +) + +(define-public (mint (who principal) (amount uint)) + (begin + (asserts! (is-eq tx-sender (var-get approved-supply-controller)) ERR-UNAUTHORIZED-MINT) + ;; amount & who are unchecked, but we let the contract owner mint to whoever they like for convenience + ;; #[allow(unchecked_data)] + (ft-mint? usda-susdt-lp amount who) + ) +) + + +(define-public (burn (burner principal) (amount uint)) + (begin + (asserts! (is-eq tx-sender burner) ERR-NOT-AUTHORIZED) + ;; amount & who are unchecked, but we let the contract owner mint to whoever they like for convenience + ;; #[allow(unchecked_data)] + (ft-burn? usda-susdt-lp amount burner) + ) +) + +;; Change the supply-controller to any other principal, can only be called the current supply-controller +(define-public (set-supply-controller (who principal)) + (begin + (asserts! (is-eq tx-sender CONTRACT-OWNER) ERR-NOT-AUTHORIZED) + ;; who is unchecked, we allow the owner to make whoever they like the new minter + ;; #[allow(unchecked_data)] + (ok (var-set approved-supply-controller who)) + ) +) + diff --git a/tests/lp-token-v2_test.ts b/tests/lp-token-v2_test.ts new file mode 100644 index 0000000..5757a42 --- /dev/null +++ b/tests/lp-token-v2_test.ts @@ -0,0 +1,67 @@ +// tests for lp-token-v2 contract +import { Clarinet, Tx, Chain, Account, types, EmptyBlock } from 'https://deno.land/x/clarinet@v1.6.0/index.ts'; +import { assertEquals } from 'https://deno.land/std@0.90.0/testing/asserts.ts'; + +// Test get-token-uri +Clarinet.test({ + name: "Ensure we can read the Token URI", + async fn(chain: Chain, accounts: Map) { + const deployer = accounts.get("deployer")!; + const wallet_1 = accounts.get("wallet_1")!; + + const call = chain.callReadOnlyFn("lp-token-v2", "get-token-uri", [], deployer.address) + + call.result.expectOk().expectSome() + console.log(JSON.stringify(call.result)); + }, +}); + +// Test contract owner setting set-token-uri +Clarinet.test({ + name: "Ensure the contract owner can set the Token URI", + async fn(chain: Chain, accounts: Map) { + const deployer = accounts.get("deployer")!; + const wallet_1 = accounts.get("wallet_1")!; + + const block = chain.mineBlock([ + Tx.contractCall("lp-token-v2", "set-token-uri", [types.utf8("https://bitflow.finance/lp-token.json")], deployer.address) + ]); + + block.receipts[0].result.expectOk() + console.log(JSON.stringify(block.receipts)); + }, +}); + +// Test get-token-uri after set-token-uri is called +Clarinet.test({ + name: "Ensure get-token-uri returns Token URI after it's set by contract owner", + async fn(chain: Chain, accounts: Map) { + const deployer = accounts.get("deployer")!; + const wallet_1 = accounts.get("wallet_1")!; + + chain.mineBlock([ + Tx.contractCall("lp-token-v2", "set-token-uri", [types.utf8("https://bitflow.finance/lp-token.json")], deployer.address) + ]); + + const call = chain.callReadOnlyFn("lp-token-v2", "get-token-uri", [], deployer.address) + + call.result.expectOk().expectSome() + console.log(JSON.stringify(call.result)); + }, +}); + +// Test user setting set-token-uri that isn't contract owner +Clarinet.test({ + name: "Ensure nobody else can set the Token URI except for contract owner", + async fn(chain: Chain, accounts: Map) { + const deployer = accounts.get("deployer")!; + const wallet_1 = accounts.get("wallet_1")!; + + const block = chain.mineBlock([ + Tx.contractCall("lp-token-v2", "set-token-uri", [types.utf8("https://bitflow.finance/lp-token.json")], wallet_1.address) + ]); + + block.receipts[0].result.expectErr() + console.log(JSON.stringify(block.receipts)); + }, +}); \ No newline at end of file