diff --git a/.github/workflows/clarinet.yml b/.github/workflows/clarinet.yml index c46eecd5..56999c48 100644 --- a/.github/workflows/clarinet.yml +++ b/.github/workflows/clarinet.yml @@ -34,7 +34,6 @@ jobs: - name: "Execute unit tests" run: npm run test:report - name: "Upload code coverage" - uses: codecov/codecov-action@v3 + uses: codecov/codecov-action@v5 with: - files: ./coverage.lcov - verbose: true + token: ${{ secrets.CODECOV_TOKEN }} diff --git a/contracts/dao/extensions/aibtc-action-proposals.clar b/contracts/dao/extensions/aibtc-action-proposals.clar index f3c8d314..58fbfee9 100644 --- a/contracts/dao/extensions/aibtc-action-proposals.clar +++ b/contracts/dao/extensions/aibtc-action-proposals.clar @@ -51,8 +51,9 @@ createdAt: uint, ;; block height caller: principal, ;; contract caller creator: principal, ;; proposal creator (tx-sender) - startBlock: uint, ;; block height - endBlock: uint, ;; block height + startBlockStx: uint, ;; block height for at-block calls + startBlock: uint, ;; burn block height + endBlock: uint, ;; burn block height votesFor: uint, ;; total votes for votesAgainst: uint, ;; total votes against liquidTokens: uint, ;; liquid tokens @@ -94,6 +95,7 @@ parameters: parameters, creator: tx-sender, liquidTokens: liquidTokens, + startBlockStx: block-height, startBlock: burn-block-height, endBlock: (+ burn-block-height VOTING_PERIOD) } @@ -105,6 +107,7 @@ createdAt: burn-block-height, caller: contract-caller, creator: tx-sender, + startBlockStx: block-height, startBlock: burn-block-height, endBlock: (+ burn-block-height VOTING_PERIOD), votesFor: u0, @@ -122,7 +125,7 @@ (let ( (proposalRecord (unwrap! (map-get? Proposals proposalId) ERR_PROPOSAL_NOT_FOUND)) - (proposalBlock (get startBlock proposalRecord)) + (proposalBlock (get startBlockStx proposalRecord)) (proposalBlockHash (unwrap! (get-block-hash proposalBlock) ERR_RETRIEVING_START_BLOCK_HASH)) (senderBalance (unwrap! (at-block proposalBlockHash (contract-call? .aibtc-token get-balance tx-sender)) ERR_FETCHING_TOKEN_DATA)) ) @@ -201,7 +204,7 @@ (let ( (proposalRecord (unwrap! (map-get? Proposals proposalId) ERR_PROPOSAL_NOT_FOUND)) - (proposalBlockHash (unwrap! (get-block-hash (get startBlock proposalRecord)) ERR_RETRIEVING_START_BLOCK_HASH)) + (proposalBlockHash (unwrap! (get-block-hash (get startBlockStx proposalRecord)) ERR_RETRIEVING_START_BLOCK_HASH)) ) (at-block proposalBlockHash (contract-call? .aibtc-token get-balance who)) ) @@ -244,7 +247,6 @@ )) ) -;; get block hash by height (define-private (get-block-hash (blockHeight uint)) (get-block-info? id-header-hash blockHeight) ) diff --git a/contracts/dao/extensions/aibtc-core-proposals.clar b/contracts/dao/extensions/aibtc-core-proposals.clar index 6418b488..79670079 100644 --- a/contracts/dao/extensions/aibtc-core-proposals.clar +++ b/contracts/dao/extensions/aibtc-core-proposals.clar @@ -18,6 +18,7 @@ (define-constant SELF (as-contract tx-sender)) (define-constant VOTING_PERIOD u144) ;; 144 Bitcoin blocks, ~1 day (define-constant VOTING_QUORUM u95) ;; 95% of liquid supply +(define-constant DEPLOYED_AT burn-block-height) ;; error messages (define-constant ERR_NOT_DAO_OR_EXTENSION (err u3000)) @@ -32,6 +33,7 @@ (define-constant ERR_VOTE_TOO_SOON (err u3009)) (define-constant ERR_VOTE_TOO_LATE (err u3010)) (define-constant ERR_ALREADY_VOTED (err u3011)) +(define-constant ERR_FIRST_VOTING_PERIOD (err u3012)) ;; contracts used for voting calculations (define-constant VOTING_TOKEN_DEX .aibtc-token-dex) @@ -46,8 +48,9 @@ createdAt: uint, ;; block height caller: principal, ;; contract caller creator: principal, ;; proposal creator (tx-sender) - startBlock: uint, ;; block height - endBlock: uint, ;; block height + startBlockStx: uint, ;; block height for at-block calls + startBlock: uint, ;; burn block height + endBlock: uint, ;; burn block height votesFor: uint, ;; total votes for votesAgainst: uint, ;; total votes against liquidTokens: uint, ;; liquid tokens @@ -77,6 +80,8 @@ (proposalContract (contract-of proposal)) (liquidTokens (try! (get-liquid-supply block-height))) ) + ;; at least one voting period passed + (asserts! (>= burn-block-height (+ DEPLOYED_AT VOTING_PERIOD)) ERR_FIRST_VOTING_PERIOD) ;; caller has the required balance (asserts! (> (unwrap! (contract-call? .aibtc-token get-balance tx-sender) ERR_FETCHING_TOKEN_DATA) u0) ERR_INSUFFICIENT_BALANCE) ;; proposal was not already executed @@ -88,6 +93,7 @@ proposal: proposalContract, creator: tx-sender, liquidTokens: liquidTokens, + startBlockStx: block-height, startBlock: burn-block-height, endBlock: (+ burn-block-height VOTING_PERIOD) } @@ -97,6 +103,7 @@ createdAt: burn-block-height, caller: contract-caller, creator: tx-sender, + startBlockStx: block-height, startBlock: burn-block-height, endBlock: (+ burn-block-height VOTING_PERIOD), votesFor: u0, @@ -112,10 +119,9 @@ ( (proposalContract (contract-of proposal)) (proposalRecord (unwrap! (map-get? Proposals proposalContract) ERR_PROPOSAL_NOT_FOUND)) - (proposalBlock (get startBlock proposalRecord)) + (proposalBlock (get startBlockStx proposalRecord)) (proposalBlockHash (unwrap! (get-block-hash proposalBlock) ERR_RETRIEVING_START_BLOCK_HASH)) - (senderBalanceResponse (at-block proposalBlockHash (contract-call? .aibtc-token get-balance tx-sender))) - (senderBalance (unwrap-panic senderBalanceResponse)) + (senderBalance (unwrap! (at-block proposalBlockHash (contract-call? .aibtc-token get-balance tx-sender)) ERR_FETCHING_TOKEN_DATA)) ) ;; caller has the required balance (asserts! (> senderBalance u0) ERR_INSUFFICIENT_BALANCE) @@ -154,8 +160,6 @@ ( (proposalContract (contract-of proposal)) (proposalRecord (unwrap! (map-get? Proposals proposalContract) ERR_PROPOSAL_NOT_FOUND)) - (tokenTotalSupply (unwrap! (contract-call? .aibtc-token get-total-supply) ERR_FETCHING_TOKEN_DATA)) - (treasuryBalance (unwrap! (contract-call? .aibtc-token get-balance .aibtc-treasury) ERR_FETCHING_TOKEN_DATA)) ;; if VOTING_QUORUM <= ((votesFor * 100) / liquidTokens) (votePassed (<= VOTING_QUORUM (/ (* (get votesFor proposalRecord) u100) (get liquidTokens proposalRecord)))) ) @@ -194,7 +198,7 @@ (let ( (proposalRecord (unwrap! (map-get? Proposals (contract-of proposal)) ERR_PROPOSAL_NOT_FOUND)) - (proposalBlockHash (unwrap! (get-block-hash (get startBlock proposalRecord)) ERR_RETRIEVING_START_BLOCK_HASH)) + (proposalBlockHash (unwrap! (get-block-hash (get startBlockStx proposalRecord)) ERR_RETRIEVING_START_BLOCK_HASH)) ) (at-block proposalBlockHash (contract-call? .aibtc-token get-balance who)) ) @@ -233,7 +237,6 @@ )) ) -;; get block hash by height (define-private (get-block-hash (blockHeight uint)) (get-block-info? id-header-hash blockHeight) ) diff --git a/contracts/dao/extensions/aibtc-token-owner.clar b/contracts/dao/extensions/aibtc-token-owner.clar index a18fb6ca..702c54b4 100644 --- a/contracts/dao/extensions/aibtc-token-owner.clar +++ b/contracts/dao/extensions/aibtc-token-owner.clar @@ -10,7 +10,7 @@ ;; constants ;; -(define-constant ERR_UNAUTHORIZED (err u401)) +(define-constant ERR_UNAUTHORIZED (err u7000)) ;; public functions ;; diff --git a/contracts/dao/proposals/aibtc-base-disable-extension.clar b/contracts/dao/proposals/aibtc-base-disable-extension.clar index 6a9cb260..48f3a09a 100644 --- a/contracts/dao/proposals/aibtc-base-disable-extension.clar +++ b/contracts/dao/proposals/aibtc-base-disable-extension.clar @@ -1,6 +1,6 @@ (impl-trait .aibtcdev-dao-traits-v1.proposal) -(define-constant ERR_EXTENSION_NOT_FOUND (err u404)) +(define-constant ERR_EXTENSION_NOT_FOUND (err u3003)) (define-public (execute (sender principal)) ;; disables an extension in the DAO diff --git a/contracts/dao/proposals/aibtc-base-enable-extension.clar b/contracts/dao/proposals/aibtc-base-enable-extension.clar index 5d518485..895fd945 100644 --- a/contracts/dao/proposals/aibtc-base-enable-extension.clar +++ b/contracts/dao/proposals/aibtc-base-enable-extension.clar @@ -1,6 +1,6 @@ (impl-trait .aibtcdev-dao-traits-v1.proposal) -(define-constant ERR_EXTENSION_NOT_FOUND (err u404)) +(define-constant ERR_EXTENSION_NOT_FOUND (err u3003)) (define-public (execute (sender principal)) ;; disables an extension in the DAO diff --git a/contracts/dao/proposals/aibtc-base-replace-extension.clar b/contracts/dao/proposals/aibtc-base-replace-extension.clar index 14c0c36c..a52a151f 100644 --- a/contracts/dao/proposals/aibtc-base-replace-extension.clar +++ b/contracts/dao/proposals/aibtc-base-replace-extension.clar @@ -1,6 +1,6 @@ (impl-trait .aibtcdev-dao-traits-v1.proposal) -(define-constant ERR_EXTENSION_NOT_FOUND (err u404)) +(define-constant ERR_EXTENSION_NOT_FOUND (err u3003)) (define-public (execute (sender principal)) ;; replaces an extension in the DAO diff --git a/deployments/default.simnet-plan.yaml b/deployments/default.simnet-plan.yaml deleted file mode 100644 index 0306fd5d..00000000 --- a/deployments/default.simnet-plan.yaml +++ /dev/null @@ -1,384 +0,0 @@ ---- -id: 0 -name: "Simulated deployment, used as a default for `clarinet console`, `clarinet test` and `clarinet check`" -network: simnet -genesis: - wallets: - - name: deployer - address: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM - balance: "100000000000000" - - name: faucet - address: STNHKEPYEPJ8ET55ZZ0M5A34J0R3N5FM2CMMMAZ6 - balance: "100000000000000" - - name: wallet_1 - address: ST1SJ3DTE5DN7X54YDH5D64R3BCB6A2AG2ZQ8YPD5 - balance: "100000000000000" - - name: wallet_2 - address: ST2CY5V39NHDPWSXMW9QDT3HC3GD6Q6XX4CFRK9AG - balance: "100000000000000" - - name: wallet_3 - address: ST2JHG361ZXG51QTKY2NQCVBPPRRE2KZB1HR05NNC - balance: "100000000000000" - - name: wallet_4 - address: ST2NEB84ASENDXKYGJPQW86YXQCEFEX2ZQPG87ND - balance: "100000000000000" - - name: wallet_5 - address: ST2REHHS5J3CERCRBEPMGH7921Q6PYKAADT7JP2VB - balance: "100000000000000" - - name: wallet_6 - address: ST3AM1A56AK2C1XAFJ4115ZSV26EB49BVQ10MGCS0 - balance: "100000000000000" - - name: wallet_7 - address: ST3PF13W7Z0RRM42A8VZRVFQ75SV1K26RXEP8YGKJ - balance: "100000000000000" - - name: wallet_8 - address: ST3NBRSFKX28FQ2ZJ1MAKX58HKHSDGNV5N7R21XCP - balance: "100000000000000" - contracts: - - costs - - pox - - pox-2 - - pox-3 - - pox-4 - - lockup - - costs-2 - - costs-3 - - cost-voting - - bns -plan: - batches: - - id: 0 - transactions: - - emulated-contract-publish: - contract-name: nft-trait - emulated-sender: SP2PABAF9FTAJYNFZH93XENAJ8FVY99RRM50D2JG9 - path: "./.cache/requirements/SP2PABAF9FTAJYNFZH93XENAJ8FVY99RRM50D2JG9.nft-trait.clar" - clarity-version: 1 - - emulated-contract-publish: - contract-name: sip-010-trait-ft-standard - emulated-sender: SP3FBR2AGK5H9QBDH3EEN6DF8EK8JY7RX8QJ5SVTE - path: "./.cache/requirements/SP3FBR2AGK5H9QBDH3EEN6DF8EK8JY7RX8QJ5SVTE.sip-010-trait-ft-standard.clar" - clarity-version: 1 - epoch: "2.1" - - id: 1 - transactions: - - emulated-contract-publish: - contract-name: sip-010-trait-ft-standard - emulated-sender: ST3VXT52QEQPZ5246A16RFNMR1PRJ96JK6YYX37N8 - path: "./.cache/requirements/ST3VXT52QEQPZ5246A16RFNMR1PRJ96JK6YYX37N8.sip-010-trait-ft-standard.clar" - clarity-version: 2 - - emulated-contract-publish: - contract-name: token-stx-v-1-2 - emulated-sender: ST295MNE41DC74QYCPRS8N37YYMC06N6Q3VQDZ6G1 - path: "./.cache/requirements/ST295MNE41DC74QYCPRS8N37YYMC06N6Q3VQDZ6G1.token-stx-v-1-2.clar" - clarity-version: 2 - - emulated-contract-publish: - contract-name: xyk-pool-trait-v-1-2 - emulated-sender: ST3VXT52QEQPZ5246A16RFNMR1PRJ96JK6YYX37N8 - path: "./.cache/requirements/ST3VXT52QEQPZ5246A16RFNMR1PRJ96JK6YYX37N8.xyk-pool-trait-v-1-2.clar" - clarity-version: 2 - - emulated-contract-publish: - contract-name: xyk-core-v-1-2 - emulated-sender: ST295MNE41DC74QYCPRS8N37YYMC06N6Q3VQDZ6G1 - path: "./.cache/requirements/ST295MNE41DC74QYCPRS8N37YYMC06N6Q3VQDZ6G1.xyk-core-v-1-2.clar" - clarity-version: 2 - epoch: "2.5" - - id: 2 - transactions: - - emulated-contract-publish: - contract-name: aibtcdev-dao-traits-v1 - emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM - path: contracts/dao/traits/aibtcdev-dao-traits-v1.clar - clarity-version: 2 - - emulated-contract-publish: - contract-name: aibtcdev-dao-v1 - emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM - path: contracts/dao/traits/aibtcdev-dao-v1.clar - clarity-version: 2 - - emulated-contract-publish: - contract-name: aibtcdev-base-dao - emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM - path: contracts/dao/aibtcdev-base-dao.clar - clarity-version: 2 - - emulated-contract-publish: - contract-name: aibtc-payments-invoices - emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM - path: contracts/dao/extensions/aibtc-payments-invoices.clar - clarity-version: 2 - - emulated-contract-publish: - contract-name: aibtc-action-add-resource - emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM - path: contracts/dao/extensions/actions/aibtc-action-add-resource.clar - clarity-version: 2 - - emulated-contract-publish: - contract-name: aibtc-treasury - emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM - path: contracts/dao/extensions/aibtc-treasury.clar - clarity-version: 2 - - emulated-contract-publish: - contract-name: aibtc-action-allow-asset - emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM - path: contracts/dao/extensions/actions/aibtc-action-allow-asset.clar - clarity-version: 2 - - emulated-contract-publish: - contract-name: aibtc-token - emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM - path: contracts/dao/extensions/aibtc-token.clar - clarity-version: 2 - - emulated-contract-publish: - contract-name: aibtc-action-proposals - emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM - path: contracts/dao/extensions/aibtc-action-proposals.clar - clarity-version: 2 - - emulated-contract-publish: - contract-name: aibtc-onchain-messaging - emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM - path: contracts/dao/extensions/aibtc-onchain-messaging.clar - clarity-version: 2 - - emulated-contract-publish: - contract-name: aibtc-action-send-message - emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM - path: contracts/dao/extensions/actions/aibtc-action-send-message.clar - clarity-version: 2 - - emulated-contract-publish: - contract-name: aibtc-bank-account - emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM - path: contracts/dao/extensions/aibtc-bank-account.clar - clarity-version: 2 - - emulated-contract-publish: - contract-name: aibtc-action-set-account-holder - emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM - path: contracts/dao/extensions/actions/aibtc-action-set-account-holder.clar - clarity-version: 2 - - emulated-contract-publish: - contract-name: aibtc-action-set-withdrawal-amount - emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM - path: contracts/dao/extensions/actions/aibtc-action-set-withdrawal-amount.clar - clarity-version: 2 - - emulated-contract-publish: - contract-name: aibtc-action-set-withdrawal-period - emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM - path: contracts/dao/extensions/actions/aibtc-action-set-withdrawal-period.clar - clarity-version: 2 - - emulated-contract-publish: - contract-name: aibtc-action-toggle-resource-by-name - emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM - path: contracts/dao/extensions/actions/aibtc-action-toggle-resource-by-name.clar - clarity-version: 2 - - emulated-contract-publish: - contract-name: aibtc-bank-account-deposit-stx - emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM - path: contracts/dao/proposals/aibtc-bank-account-deposit-stx.clar - clarity-version: 2 - - emulated-contract-publish: - contract-name: aibtc-bank-account-initialize-new-account - emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM - path: contracts/dao/proposals/aibtc-bank-account-initialize-new-account.clar - clarity-version: 2 - - emulated-contract-publish: - contract-name: aibtc-bank-account-override-last-withdrawal-block - emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM - path: contracts/dao/proposals/aibtc-bank-account-override-last-withdrawal-block.clar - clarity-version: 2 - - emulated-contract-publish: - contract-name: aibtc-bank-account-set-account-holder - emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM - path: contracts/dao/proposals/aibtc-bank-account-set-account-holder.clar - clarity-version: 2 - - emulated-contract-publish: - contract-name: aibtc-bank-account-set-withdrawal-amount - emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM - path: contracts/dao/proposals/aibtc-bank-account-set-withdrawal-amount.clar - clarity-version: 2 - - emulated-contract-publish: - contract-name: aibtc-bank-account-set-withdrawal-period - emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM - path: contracts/dao/proposals/aibtc-bank-account-set-withdrawal-period.clar - clarity-version: 2 - - emulated-contract-publish: - contract-name: aibtc-bank-account-withdraw-stx - emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM - path: contracts/dao/proposals/aibtc-bank-account-withdraw-stx.clar - clarity-version: 2 - - emulated-contract-publish: - contract-name: aibtc-base-add-new-extension - emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM - path: contracts/dao/proposals/aibtc-base-add-new-extension.clar - clarity-version: 2 - - emulated-contract-publish: - contract-name: aibtc-base-bootstrap-initialization - emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM - path: contracts/dao/proposals/aibtc-base-bootstrap-initialization.clar - clarity-version: 2 - epoch: "3.0" - - id: 3 - transactions: - - emulated-contract-publish: - contract-name: aibtc-base-disable-extension - emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM - path: contracts/dao/proposals/aibtc-base-disable-extension.clar - clarity-version: 2 - - emulated-contract-publish: - contract-name: aibtc-base-enable-extension - emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM - path: contracts/dao/proposals/aibtc-base-enable-extension.clar - clarity-version: 2 - - emulated-contract-publish: - contract-name: aibtc-base-replace-extension - emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM - path: contracts/dao/proposals/aibtc-base-replace-extension.clar - clarity-version: 2 - - emulated-contract-publish: - contract-name: aibtc-bitflow-pool - emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM - path: contracts/dao/extensions/aibtc-bitflow-pool.clar - clarity-version: 2 - - emulated-contract-publish: - contract-name: aibtc-core-proposals - emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM - path: contracts/dao/extensions/aibtc-core-proposals.clar - clarity-version: 2 - - emulated-contract-publish: - contract-name: aibtc-onchain-messaging-send - emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM - path: contracts/dao/proposals/aibtc-onchain-messaging-send.clar - clarity-version: 2 - - emulated-contract-publish: - contract-name: aibtc-payments-invoices-add-resource - emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM - path: contracts/dao/proposals/aibtc-payments-invoices-add-resource.clar - clarity-version: 2 - - emulated-contract-publish: - contract-name: aibtc-payments-invoices-pay-invoice - emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM - path: contracts/dao/proposals/aibtc-payments-invoices-pay-invoice.clar - clarity-version: 2 - - emulated-contract-publish: - contract-name: aibtc-payments-invoices-pay-invoice-by-resource-name - emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM - path: contracts/dao/proposals/aibtc-payments-invoices-pay-invoice-by-resource-name.clar - clarity-version: 2 - - emulated-contract-publish: - contract-name: aibtc-payments-invoices-set-payment-address - emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM - path: contracts/dao/proposals/aibtc-payments-invoices-set-payment-address.clar - clarity-version: 2 - - emulated-contract-publish: - contract-name: aibtc-payments-invoices-toggle-resource - emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM - path: contracts/dao/proposals/aibtc-payments-invoices-toggle-resource.clar - clarity-version: 2 - - emulated-contract-publish: - contract-name: aibtc-payments-invoices-toggle-resource-by-name - emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM - path: contracts/dao/proposals/aibtc-payments-invoices-toggle-resource-by-name.clar - clarity-version: 2 - - emulated-contract-publish: - contract-name: aibtc-token-dex - emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM - path: contracts/dao/extensions/aibtc-token-dex.clar - clarity-version: 2 - - emulated-contract-publish: - contract-name: aibtc-token-owner - emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM - path: contracts/dao/extensions/aibtc-token-owner.clar - clarity-version: 2 - - emulated-contract-publish: - contract-name: aibtc-token-owner-set-token-uri - emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM - path: contracts/dao/proposals/aibtc-token-owner-set-token-uri.clar - clarity-version: 2 - - emulated-contract-publish: - contract-name: aibtc-token-owner-transfer-ownership - emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM - path: contracts/dao/proposals/aibtc-token-owner-transfer-ownership.clar - clarity-version: 2 - - emulated-contract-publish: - contract-name: aibtc-treasury-allow-asset - emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM - path: contracts/dao/proposals/aibtc-treasury-allow-asset.clar - clarity-version: 2 - - emulated-contract-publish: - contract-name: aibtc-treasury-delegate-stx - emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM - path: contracts/dao/proposals/aibtc-treasury-delegate-stx.clar - clarity-version: 2 - - emulated-contract-publish: - contract-name: aibtc-treasury-deposit-ft - emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM - path: contracts/dao/proposals/aibtc-treasury-deposit-ft.clar - clarity-version: 2 - - emulated-contract-publish: - contract-name: aibtcdev-airdrop-1 - emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM - path: contracts/aibtcdev-airdrop-1.clar - clarity-version: 2 - - emulated-contract-publish: - contract-name: aibtc-treasury-deposit-nft - emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM - path: contracts/dao/proposals/aibtc-treasury-deposit-nft.clar - clarity-version: 2 - - emulated-contract-publish: - contract-name: aibtc-treasury-deposit-stx - emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM - path: contracts/dao/proposals/aibtc-treasury-deposit-stx.clar - clarity-version: 2 - - emulated-contract-publish: - contract-name: aibtc-treasury-freeze-asset - emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM - path: contracts/dao/proposals/aibtc-treasury-freeze-asset.clar - clarity-version: 2 - - emulated-contract-publish: - contract-name: aibtc-treasury-revoke-delegation - emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM - path: contracts/dao/proposals/aibtc-treasury-revoke-delegation.clar - clarity-version: 2 - - emulated-contract-publish: - contract-name: aibtc-treasury-withdraw-ft - emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM - path: contracts/dao/proposals/aibtc-treasury-withdraw-ft.clar - clarity-version: 2 - epoch: "3.0" - - id: 4 - transactions: - - emulated-contract-publish: - contract-name: aibtc-treasury-withdraw-nft - emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM - path: contracts/dao/proposals/aibtc-treasury-withdraw-nft.clar - clarity-version: 2 - - emulated-contract-publish: - contract-name: aibtc-treasury-withdraw-stx - emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM - path: contracts/dao/proposals/aibtc-treasury-withdraw-stx.clar - clarity-version: 2 - - emulated-contract-publish: - contract-name: aibtcdev-airdrop-2 - emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM - path: contracts/aibtcdev-airdrop-2.clar - clarity-version: 2 - - emulated-contract-publish: - contract-name: proxy - emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM - path: contracts/test/proxy.clar - clarity-version: 2 - - emulated-contract-publish: - contract-name: test-proxy - emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM - path: contracts/test/proxy.clar - clarity-version: 2 - - emulated-contract-publish: - contract-name: test-token - emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM - path: contracts/test/sip010-token.clar - clarity-version: 2 - - emulated-contract-publish: - contract-name: test-treasury - emulated-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM - path: contracts/test/aibtc-treasury.clar - clarity-version: 2 - - emulated-contract-publish: - contract-name: external-proxy - emulated-sender: ST1SJ3DTE5DN7X54YDH5D64R3BCB6A2AG2ZQ8YPD5 - path: contracts/test/proxy.clar - clarity-version: 2 - epoch: "3.0" diff --git a/tests/dao/aibtcdev-base-dao.test.ts b/tests/dao/aibtcdev-base-dao.test.ts index ae95145a..d9863f22 100644 --- a/tests/dao/aibtcdev-base-dao.test.ts +++ b/tests/dao/aibtcdev-base-dao.test.ts @@ -1,21 +1,18 @@ import { Cl } from "@stacks/transactions"; import { describe, expect, it } from "vitest"; +import { BaseDaoErrCode } from "../error-codes"; const accounts = simnet.getAccounts(); const address1 = accounts.get("wallet_1")!; const address2 = accounts.get("wallet_2")!; const deployer = accounts.get("deployer")!; -const contractAddress = `${deployer}.aibtcdev-base-dao`; +const contractName = "aibtcdev-base-dao"; +const contractAddress = `${deployer}.${contractName}`; -enum ErrCode { - ERR_UNAUTHORIZED = 1000, - ERR_NOT_DAO_OR_EXTENSION = 1001, - ERR_ALREADY_EXECUTED = 1002, - ERR_INVALID_EXTENSION = 1003, -} +const ErrCode = BaseDaoErrCode; -describe("aibtcdev-base-dao", () => { +describe(`base dao: ${contractName}`, () => { it("should have tests written", () => { expect(true).toBe(true); }); diff --git a/tests/dao/extensions/actions/aibtc-action-add-resource.test.ts b/tests/dao/extensions/actions/aibtc-action-add-resource.test.ts index 00f18463..d508e73e 100644 --- a/tests/dao/extensions/actions/aibtc-action-add-resource.test.ts +++ b/tests/dao/extensions/actions/aibtc-action-add-resource.test.ts @@ -4,9 +4,10 @@ import { describe, expect, it } from "vitest"; const accounts = simnet.getAccounts(); const deployer = accounts.get("deployer")!; -const contractAddress = `${deployer}.aibtc-action-add-resource`; +const contractName = "aibtc-action-add-resource"; +const contractAddress = `${deployer}.${contractName}`; -describe("aibtc-action-add-resource", () => { +describe(`action extension: ${contractName}`, () => { it("callback() should respond with (ok true)", () => { const callback = simnet.callPublicFn( contractAddress, diff --git a/tests/dao/extensions/actions/aibtc-action-allow-asset.test.ts b/tests/dao/extensions/actions/aibtc-action-allow-asset.test.ts index 1519f018..57a95501 100644 --- a/tests/dao/extensions/actions/aibtc-action-allow-asset.test.ts +++ b/tests/dao/extensions/actions/aibtc-action-allow-asset.test.ts @@ -4,9 +4,10 @@ import { describe, expect, it } from "vitest"; const accounts = simnet.getAccounts(); const deployer = accounts.get("deployer")!; -const contractAddress = `${deployer}.aibtc-action-add-resource`; +const contractName = "aibtc-action-allow-asset"; +const contractAddress = `${deployer}.${contractName}`; -describe("aibtc-action-allow-asset", () => { +describe(`action extension: ${contractName}`, () => { it("callback() should respond with (ok true)", () => { const callback = simnet.callPublicFn( contractAddress, diff --git a/tests/dao/extensions/actions/aibtc-action-send-message.test.ts b/tests/dao/extensions/actions/aibtc-action-send-message.test.ts index c3b416f5..920c501d 100644 --- a/tests/dao/extensions/actions/aibtc-action-send-message.test.ts +++ b/tests/dao/extensions/actions/aibtc-action-send-message.test.ts @@ -1,12 +1,22 @@ -import { Cl } from "@stacks/transactions"; +import { Cl, cvToValue } from "@stacks/transactions"; import { describe, expect, it } from "vitest"; +import { + constructDao, + fundVoters, + getDaoTokens, + passActionProposal, +} from "../../../test-utilities"; +import { ActionErrCode } from "../../../error-codes"; const accounts = simnet.getAccounts(); const deployer = accounts.get("deployer")!; +const address1 = accounts.get("wallet_1")!; +const address2 = accounts.get("wallet_2")!; -const contractAddress = `${deployer}.aibtc-action-add-resource`; +const contractName = "aibtc-action-send-message"; +const contractAddress = `${deployer}.${contractName}`; -describe("aibtc-action-send-message", () => { +describe(`action extension: ${contractName}`, () => { it("callback() should respond with (ok true)", () => { const callback = simnet.callPublicFn( contractAddress, @@ -16,4 +26,68 @@ describe("aibtc-action-send-message", () => { ); expect(callback.result).toBeOk(Cl.bool(true)); }); + + it("run() fails if called directly", () => { + const message = "hello world"; + const receipt = simnet.callPublicFn( + contractAddress, + "run", + [Cl.buffer(Cl.serialize(Cl.stringAscii(message)))], + deployer + ); + expect(receipt.result).toBeErr(Cl.uint(ActionErrCode.ERR_UNAUTHORIZED)); + }); + + it("run() succeeds if called as a DAO action proposal", () => { + const message = "hello world"; + // fund accounts for creating and voting on proposals + fundVoters(deployer, [deployer, address1, address2]); + + // construct DAO + const constructReceipt = constructDao(deployer); + expect(constructReceipt.result).toBeOk(Cl.bool(true)); + + // progress the chain for at-block calls + simnet.mineEmptyBlocks(10); + + // pass action proposal + const concludeProposalReceipt = passActionProposal( + contractAddress, + Cl.stringAscii(message), + deployer, + deployer, + [deployer, address1, address2] + ); + + /* + console.log("==========================="); + console.log("concludeProposalReceipt"); + console.log(concludeProposalReceipt); + console.log("events:"); + for (const event of concludeProposalReceipt.events) { + const eventValue = cvToValue(event.data.value!); + // if event value is an object stringify it + console.log( + `${ + typeof eventValue === "object" + ? JSON.stringify(eventValue) + : eventValue + }` + ); + } + + const proposalDetails = simnet.callReadOnlyFn( + `${deployer}.aibtc-action-proposals`, + "get-proposal", + [Cl.uint(1)], + deployer + ); + + console.log("==========================="); + console.log("proposalDetails"); + console.log(cvToValue(proposalDetails.result).value); + */ + + expect(concludeProposalReceipt.result).toBeOk(Cl.bool(true)); + }); }); diff --git a/tests/dao/extensions/actions/aibtc-action-set-account-holder.test.ts b/tests/dao/extensions/actions/aibtc-action-set-account-holder.test.ts index 53faf991..0a8636ec 100644 --- a/tests/dao/extensions/actions/aibtc-action-set-account-holder.test.ts +++ b/tests/dao/extensions/actions/aibtc-action-set-account-holder.test.ts @@ -4,9 +4,10 @@ import { describe, expect, it } from "vitest"; const accounts = simnet.getAccounts(); const deployer = accounts.get("deployer")!; -const contractAddress = `${deployer}.aibtc-action-add-resource`; +const contractName = "aibtc-action-set-account-holder"; +const contractAddress = `${deployer}.${contractName}`; -describe("aibtc-action-set-account-holder", () => { +describe(`action extension: ${contractName}`, () => { it("callback() should respond with (ok true)", () => { const callback = simnet.callPublicFn( contractAddress, diff --git a/tests/dao/extensions/actions/aibtc-action-set-withdrawal-amount.test.ts b/tests/dao/extensions/actions/aibtc-action-set-withdrawal-amount.test.ts index b659104c..182f90a1 100644 --- a/tests/dao/extensions/actions/aibtc-action-set-withdrawal-amount.test.ts +++ b/tests/dao/extensions/actions/aibtc-action-set-withdrawal-amount.test.ts @@ -4,9 +4,10 @@ import { describe, expect, it } from "vitest"; const accounts = simnet.getAccounts(); const deployer = accounts.get("deployer")!; -const contractAddress = `${deployer}.aibtc-action-add-resource`; +const contractName = "aibtc-action-set-withdrawal-amount"; +const contractAddress = `${deployer}.${contractName}`; -describe("aibtc-action-set-withdrawal-amount", () => { +describe(`action extension: ${contractName}`, () => { it("callback() should respond with (ok true)", () => { const callback = simnet.callPublicFn( contractAddress, diff --git a/tests/dao/extensions/actions/aibtc-action-set-withdrawal-period.test.ts b/tests/dao/extensions/actions/aibtc-action-set-withdrawal-period.test.ts index bf0c8df5..1c2b699a 100644 --- a/tests/dao/extensions/actions/aibtc-action-set-withdrawal-period.test.ts +++ b/tests/dao/extensions/actions/aibtc-action-set-withdrawal-period.test.ts @@ -4,9 +4,10 @@ import { describe, expect, it } from "vitest"; const accounts = simnet.getAccounts(); const deployer = accounts.get("deployer")!; -const contractAddress = `${deployer}.aibtc-action-add-resource`; +const contractName = "aibtc-action-set-withdrawal-period"; +const contractAddress = `${deployer}.${contractName}`; -describe("aibtc-action-set-withdrawal-period", () => { +describe(`action extension: ${contractName}`, () => { it("callback() should respond with (ok true)", () => { const callback = simnet.callPublicFn( contractAddress, diff --git a/tests/dao/extensions/actions/aibtc-action-toggle-resource-by-name.test.ts b/tests/dao/extensions/actions/aibtc-action-toggle-resource-by-name.test.ts index 48b4ac5b..5f9ec210 100644 --- a/tests/dao/extensions/actions/aibtc-action-toggle-resource-by-name.test.ts +++ b/tests/dao/extensions/actions/aibtc-action-toggle-resource-by-name.test.ts @@ -4,9 +4,10 @@ import { describe, expect, it } from "vitest"; const accounts = simnet.getAccounts(); const deployer = accounts.get("deployer")!; -const contractAddress = `${deployer}.aibtc-action-add-resource`; +const contractName = "aibtc-action-toggle-resource-by-name"; +const contractAddress = `${deployer}.${contractName}`; -describe("aibtc-action-toggle-resource-by-name", () => { +describe(`action extension: ${contractName}`, () => { it("callback() should respond with (ok true)", () => { const callback = simnet.callPublicFn( contractAddress, diff --git a/tests/dao/extensions/aibtc-action-proposals.test.ts b/tests/dao/extensions/aibtc-action-proposals.test.ts index 15f156dd..a6a3c456 100644 --- a/tests/dao/extensions/aibtc-action-proposals.test.ts +++ b/tests/dao/extensions/aibtc-action-proposals.test.ts @@ -1,32 +1,21 @@ import { Cl } from "@stacks/transactions"; import { describe, expect, it } from "vitest"; +import { ActionProposalsErrCode } from "../../error-codes"; const accounts = simnet.getAccounts(); const address1 = accounts.get("wallet_1")!; const address2 = accounts.get("wallet_2")!; const deployer = accounts.get("deployer")!; -const contractAddress = `${deployer}.aibtc-action-proposals`; - -export enum ErrCode { - ERR_NOT_DAO_OR_EXTENSION = 1000, - ERR_INSUFFICIENT_BALANCE, - ERR_FETCHING_TOKEN_DATA, - ERR_PROPOSAL_NOT_FOUND, - ERR_PROPOSAL_STILL_ACTIVE, - ERR_SAVING_PROPOSAL, - ERR_PROPOSAL_ALREADY_CONCLUDED, - ERR_RETRIEVING_START_BLOCK_HASH, - ERR_VOTE_TOO_SOON, - ERR_VOTE_TOO_LATE, - ERR_ALREADY_VOTED, - ERR_INVALID_ACTION, -} +const contractName = "aibtc-action-proposals"; +const contractAddress = `${deployer}.${contractName}`; const votingPeriod = 144; // 24 hours in BTC blocks const votingQuorum = 66; // 66% quorum -describe("aibtc-action-proposals", () => { +const ErrCode = ActionProposalsErrCode; + +describe(`extension: ${contractName}`, () => { it("callback() should respond with (ok true)", () => { const callback = simnet.callPublicFn( contractAddress, diff --git a/tests/dao/extensions/aibtc-bank-account.test.ts b/tests/dao/extensions/aibtc-bank-account.test.ts index b7f6c132..87f585f2 100644 --- a/tests/dao/extensions/aibtc-bank-account.test.ts +++ b/tests/dao/extensions/aibtc-bank-account.test.ts @@ -1,24 +1,21 @@ import { Cl } from "@stacks/transactions"; import { describe, expect, it } from "vitest"; +import { BankAccountErrCode } from "../../error-codes"; const accounts = simnet.getAccounts(); const address1 = accounts.get("wallet_1")!; const address2 = accounts.get("wallet_2")!; const deployer = accounts.get("deployer")!; -const contractAddress = `${deployer}.aibtc-bank-account`; +const contractName = "aibtc-bank-account"; +const contractAddress = `${deployer}.${contractName}`; -enum ErrCode { - ERR_INVALID = 2000, - ERR_UNAUTHORIZED, - ERR_TOO_SOON, - ERR_INVALID_AMOUNT, -} +const ErrCode = BankAccountErrCode; const withdrawalAmount = 10000000; // 10 STX const withdrawalPeriod = 144; // 144 blocks -describe("aibtc-bank-account", () => { +describe(`extension: ${contractName}`, () => { it("callback() should respond with (ok true)", () => { const callback = simnet.callPublicFn( contractAddress, diff --git a/tests/dao/extensions/aibtc-core-proposals.test.ts b/tests/dao/extensions/aibtc-core-proposals.test.ts index a106c08e..491fadfd 100644 --- a/tests/dao/extensions/aibtc-core-proposals.test.ts +++ b/tests/dao/extensions/aibtc-core-proposals.test.ts @@ -1,30 +1,19 @@ import { Cl } from "@stacks/transactions"; import { describe, expect, it } from "vitest"; +import { CoreProposalErrCode } from "../../error-codes"; const accounts = simnet.getAccounts(); const deployer = accounts.get("deployer")!; -const contractAddress = `${deployer}.aibtc-core-proposals`; +const contractName = "aibtc-core-proposals"; +const contractAddress = `${deployer}.${contractName}`; -export enum ErrCode { - ERR_NOT_DAO_OR_EXTENSION = 3000, - ERR_FETCHING_TOKEN_DATA, - ERR_INSUFFICIENT_BALANCE, - ERR_PROPOSAL_NOT_FOUND, - ERR_PROPOSAL_ALREADY_EXECUTED, - ERR_PROPOSAL_STILL_ACTIVE, - ERR_SAVING_PROPOSAL, - ERR_PROPOSAL_ALREADY_CONCLUDED, - ERR_RETRIEVING_START_BLOCK_HASH, - ERR_VOTE_TOO_SOON, - ERR_VOTE_TOO_LATE, - ERR_ALREADY_VOTED, -} +const ErrCode = CoreProposalErrCode; const votingPeriod = 144; // 24 hours in BTC blocks const votingQuorum = 95; // 95% quorum -describe("aibtc-core-proposals", () => { +describe(`extension: ${contractName}`, () => { it("callback() should respond with (ok true)", () => { const callback = simnet.callPublicFn( contractAddress, diff --git a/tests/dao/extensions/aibtc-onchain-messaging.test.ts b/tests/dao/extensions/aibtc-onchain-messaging.test.ts index 71576517..2d6c38fa 100644 --- a/tests/dao/extensions/aibtc-onchain-messaging.test.ts +++ b/tests/dao/extensions/aibtc-onchain-messaging.test.ts @@ -1,19 +1,24 @@ -import { Cl } from "@stacks/transactions"; +import { Cl, cvToValue } from "@stacks/transactions"; import { describe, expect, it } from "vitest"; +import { + constructDao, + fundVoters, + getDaoTokens, + passCoreProposal, +} from "../../test-utilities"; +import { OnchainMessagingErrCode } from "../../error-codes"; const accounts = simnet.getAccounts(); +const deployer = accounts.get("deployer")!; const address1 = accounts.get("wallet_1")!; const address2 = accounts.get("wallet_2")!; -const deployer = accounts.get("deployer")!; -const contractAddress = `${deployer}.aibtc-onchain-messaging`; +const contractName = "aibtc-onchain-messaging"; +const contractAddress = `${deployer}.${contractName}`; -export enum ErrCode { - INPUT_ERROR = 4000, - ERR_UNAUTHORIZED, -} +const ErrCode = OnchainMessagingErrCode; -describe("aibtc-onchain-messaging", () => { +describe(`extension: ${contractName}`, () => { it("callback() should respond with (ok true)", () => { const callback = simnet.callPublicFn( contractAddress, @@ -23,12 +28,80 @@ describe("aibtc-onchain-messaging", () => { ); expect(callback.result).toBeOk(Cl.bool(true)); }); - /* - // Message Tests - describe("send()", () => { - it("succeeds if called by any user with isFromDao false"); - it("fails if called by any user with isFromDao true"); - it("succeeds if called by a DAO proposal with isFromDao true"); + + it("send() succeeds if called by any user with isFromDao false", () => { + const message = "test"; + const receipt = simnet.callPublicFn( + contractAddress, + "send", + [Cl.stringAscii(message), Cl.bool(false)], + address1 + ); + expect(receipt.result).toBeOk(Cl.bool(true)); + }); + + it("send() fails if called by any user with isFromDao true", () => { + const message = "test"; + const receipt = simnet.callPublicFn( + contractAddress, + "send", + [Cl.stringAscii(message), Cl.bool(true)], + address1 + ); + expect(receipt.result).toBeErr(Cl.uint(ErrCode.ERR_UNAUTHORIZED)); + }); + + it("send() succeeds if called by a DAO proposal with isFromDao true", () => { + const proposalContractName = "aibtc-onchain-messaging-send"; + const proposalContractAddress = `${deployer}.${proposalContractName}`; + + // fund accounts for creating and voting on proposals + fundVoters(deployer, [deployer, address1, address2]); + + // construct DAO + const constructReceipt = constructDao(deployer); + expect(constructReceipt.result).toBeOk(Cl.bool(true)); + + // progress the chain for at-block calls + // and to pass first core proposal voting period + simnet.mineEmptyBlocks(144); + + // pass proposal + const concludeProposalReceipt = passCoreProposal( + proposalContractAddress, + deployer, + [deployer, address1, address2] + ); + + /* + console.log("==========================="); + console.log("concludeProposalReceipt"); + console.log(concludeProposalReceipt); + for (const event of concludeProposalReceipt.events) { + const eventValue = cvToValue(event.data.value!); + // if event value is an object stringify it + console.log( + `- event: ${ + typeof eventValue === "object" + ? JSON.stringify(eventValue) + : eventValue + }` + ); + } + + + const proposalDetails = simnet.callReadOnlyFn( + `${deployer}.aibtc-core-proposals`, + "get-proposal", + [Cl.principal(proposalContractAddress)], + deployer + ); + + console.log("==========================="); + console.log("proposalDetails"); + console.log(cvToValue(proposalDetails.result).value); + */ + + expect(concludeProposalReceipt.result).toBeOk(Cl.bool(true)); }); - */ }); diff --git a/tests/dao/extensions/aibtc-payments-invoices.test.ts b/tests/dao/extensions/aibtc-payments-invoices.test.ts index 6c4d047e..01be3c56 100644 --- a/tests/dao/extensions/aibtc-payments-invoices.test.ts +++ b/tests/dao/extensions/aibtc-payments-invoices.test.ts @@ -1,31 +1,18 @@ import { Cl } from "@stacks/transactions"; import { describe, expect, it } from "vitest"; +import { PaymentsInvoicesErrCode } from "../../error-codes"; const accounts = simnet.getAccounts(); const address1 = accounts.get("wallet_1")!; const address2 = accounts.get("wallet_2")!; const deployer = accounts.get("deployer")!; -const contractAddress = `${deployer}.aibtc-payments-invoices`; +const contractName = "aibtc-payments-invoices"; +const contractAddress = `${deployer}.${contractName}`; -enum ErrCode { - ERR_UNAUTHORIZED = 5000, - ERR_INVALID_PARAMS, - ERR_NAME_ALREADY_USED, - ERR_SAVING_RESOURCE_DATA, - ERR_DELETING_RESOURCE_DATA, - ERR_RESOURCE_NOT_FOUND, - ERR_RESOURCE_DISABLED, - ERR_USER_ALREADY_EXISTS, - ERR_SAVING_USER_DATA, - ERR_USER_NOT_FOUND, - ERR_INVOICE_ALREADY_PAID, - ERR_SAVING_INVOICE_DATA, - ERR_INVOICE_NOT_FOUND, - ERR_RECENT_PAYMENT_NOT_FOUND, -} +const ErrCode = PaymentsInvoicesErrCode; -describe("aibtc-payments-invoices", () => { +describe(`extension: ${contractName}`, () => { it("callback() should respond with (ok true)", () => { const callback = simnet.callPublicFn( contractAddress, diff --git a/tests/dao/extensions/aibtc-token-owner.test.ts b/tests/dao/extensions/aibtc-token-owner.test.ts index 3cab3dd3..2494c957 100644 --- a/tests/dao/extensions/aibtc-token-owner.test.ts +++ b/tests/dao/extensions/aibtc-token-owner.test.ts @@ -1,12 +1,16 @@ import { Cl } from "@stacks/transactions"; import { describe, expect, it } from "vitest"; +import { TokenOwnerErrCode } from "../../error-codes"; const accounts = simnet.getAccounts(); const deployer = accounts.get("deployer")!; -const contractAddress = `${deployer}.aibtc-token-owner`; +const contractName = "aibtc-token-owner"; +const contractAddress = `${deployer}.${contractName}`; -describe("aibtc-token-owner", () => { +const ErrCode = TokenOwnerErrCode; + +describe(`extension: ${contractName}`, () => { it("callback() should respond with (ok true)", () => { const callback = simnet.callPublicFn( contractAddress, diff --git a/tests/dao/extensions/aibtc-treasury.test.ts b/tests/dao/extensions/aibtc-treasury.test.ts index 67f5ef1e..cffe6177 100644 --- a/tests/dao/extensions/aibtc-treasury.test.ts +++ b/tests/dao/extensions/aibtc-treasury.test.ts @@ -1,19 +1,18 @@ import { Cl } from "@stacks/transactions"; import { describe, expect, it } from "vitest"; +import { TreasuryErrCode } from "../../error-codes"; const accounts = simnet.getAccounts(); const address1 = accounts.get("wallet_1")!; const address2 = accounts.get("wallet_2")!; const deployer = accounts.get("deployer")!; -const contractAddress = `${deployer}.aibtc-treasury`; +const contractName = "aibtc-treasury"; +const contractAddress = `${deployer}.${contractName}`; -enum ErrCode { - ERR_UNAUTHORIZED = 6000, - ERR_UNKNOWN_ASSSET = 6001, -} +const ErrCode = TreasuryErrCode; -describe("aibtc-treasury", () => { +describe(`extension: ${contractName}`, () => { it("callback() should respond with (ok true)", () => { const callback = simnet.callPublicFn( contractAddress, diff --git a/tests/dao/proposals/aibtc-bank-account-deposit-stx.test.ts b/tests/dao/proposals/aibtc-bank-account-deposit-stx.test.ts index 8f5ff5cc..f49315eb 100644 --- a/tests/dao/proposals/aibtc-bank-account-deposit-stx.test.ts +++ b/tests/dao/proposals/aibtc-bank-account-deposit-stx.test.ts @@ -1,7 +1,23 @@ +import { Cl } from "@stacks/transactions"; import { describe, expect, it } from "vitest"; -describe("aibtc-bank-account-deposit-stx", () => { - it("should have tests written", () => { - expect(true).toBe(true); +const accounts = simnet.getAccounts(); +const deployer = accounts.get("deployer")!; +const contractName = "aibtc-bank-account-deposit-stx"; +const contractAddress = `${deployer}.${contractName}`; + +// normally would succeed (anyone can call) +// fails because contract has no funds to deposit +const expectedErr = Cl.uint(4); + +describe(`core proposal: ${contractName}`, () => { + it("execute() fails if called directly", () => { + const receipt = simnet.callPublicFn( + contractAddress, + "execute", + [Cl.principal(deployer)], + deployer + ); + expect(receipt.result).toBeErr(expectedErr); }); }); diff --git a/tests/dao/proposals/aibtc-bank-account-initialize-new-account.test.ts b/tests/dao/proposals/aibtc-bank-account-initialize-new-account.test.ts index 45a2e819..c2976bc2 100644 --- a/tests/dao/proposals/aibtc-bank-account-initialize-new-account.test.ts +++ b/tests/dao/proposals/aibtc-bank-account-initialize-new-account.test.ts @@ -1,7 +1,22 @@ +import { Cl } from "@stacks/transactions"; import { describe, expect, it } from "vitest"; +import { BankAccountErrCode } from "../../error-codes"; -describe("aibtc-bank-account-initialize-new", () => { - it("should have tests written", () => { - expect(true).toBe(true); +const accounts = simnet.getAccounts(); +const deployer = accounts.get("deployer")!; +const contractName = "aibtc-bank-account-initialize-new-account"; +const contractAddress = `${deployer}.${contractName}`; + +const expectedErr = Cl.uint(BankAccountErrCode.ERR_UNAUTHORIZED); + +describe(`core proposal: ${contractName}`, () => { + it("execute() fails if called directly", () => { + const receipt = simnet.callPublicFn( + contractAddress, + "execute", + [Cl.principal(deployer)], + deployer + ); + expect(receipt.result).toBeErr(expectedErr); }); }); diff --git a/tests/dao/proposals/aibtc-bank-account-override-last-withdrawal-block.test.ts b/tests/dao/proposals/aibtc-bank-account-override-last-withdrawal-block.test.ts index c56ca079..5d82e484 100644 --- a/tests/dao/proposals/aibtc-bank-account-override-last-withdrawal-block.test.ts +++ b/tests/dao/proposals/aibtc-bank-account-override-last-withdrawal-block.test.ts @@ -1,7 +1,22 @@ +import { Cl } from "@stacks/transactions"; import { describe, expect, it } from "vitest"; +import { BankAccountErrCode } from "../../error-codes"; -describe("aibtc-bank-account-override-last-withdrawal-block", () => { - it("should have tests written", () => { - expect(true).toBe(true); +const accounts = simnet.getAccounts(); +const deployer = accounts.get("deployer")!; +const contractName = "aibtc-bank-account-override-last-withdrawal-block"; +const contractAddress = `${deployer}.${contractName}`; + +const expectedErr = Cl.uint(BankAccountErrCode.ERR_UNAUTHORIZED); + +describe(`core proposal: ${contractName}`, () => { + it("execute() fails if called directly", () => { + const receipt = simnet.callPublicFn( + contractAddress, + "execute", + [Cl.principal(deployer)], + deployer + ); + expect(receipt.result).toBeErr(expectedErr); }); }); diff --git a/tests/dao/proposals/aibtc-bank-account-set-account-holder.test.ts b/tests/dao/proposals/aibtc-bank-account-set-account-holder.test.ts index e3bb2950..f08cc534 100644 --- a/tests/dao/proposals/aibtc-bank-account-set-account-holder.test.ts +++ b/tests/dao/proposals/aibtc-bank-account-set-account-holder.test.ts @@ -1,7 +1,22 @@ +import { Cl } from "@stacks/transactions"; import { describe, expect, it } from "vitest"; +import { BankAccountErrCode } from "../../error-codes"; -describe("aibtc-bank-account-set-account-holder", () => { - it("should have tests written", () => { - expect(true).toBe(true); +const accounts = simnet.getAccounts(); +const deployer = accounts.get("deployer")!; +const contractName = "aibtc-bank-account-set-account-holder"; +const contractAddress = `${deployer}.${contractName}`; + +const expectedErr = Cl.uint(BankAccountErrCode.ERR_UNAUTHORIZED); + +describe(`core proposal: ${contractName}`, () => { + it("execute() fails if called directly", () => { + const receipt = simnet.callPublicFn( + contractAddress, + "execute", + [Cl.principal(deployer)], + deployer + ); + expect(receipt.result).toBeErr(expectedErr); }); }); diff --git a/tests/dao/proposals/aibtc-bank-account-set-withdrawal-amount.test.ts b/tests/dao/proposals/aibtc-bank-account-set-withdrawal-amount.test.ts index bfe55d33..9780b311 100644 --- a/tests/dao/proposals/aibtc-bank-account-set-withdrawal-amount.test.ts +++ b/tests/dao/proposals/aibtc-bank-account-set-withdrawal-amount.test.ts @@ -1,7 +1,22 @@ +import { Cl } from "@stacks/transactions"; import { describe, expect, it } from "vitest"; +import { BankAccountErrCode } from "../../error-codes"; -describe("aibtc-bank-account-set-withdrawal-amount", () => { - it("should have tests written", () => { - expect(true).toBe(true); +const accounts = simnet.getAccounts(); +const deployer = accounts.get("deployer")!; +const contractName = "aibtc-bank-account-set-withdrawal-amount"; +const contractAddress = `${deployer}.${contractName}`; + +const expectedErr = Cl.uint(BankAccountErrCode.ERR_UNAUTHORIZED); + +describe(`core proposal: ${contractName}`, () => { + it("execute() fails if called directly", () => { + const receipt = simnet.callPublicFn( + contractAddress, + "execute", + [Cl.principal(deployer)], + deployer + ); + expect(receipt.result).toBeErr(expectedErr); }); }); diff --git a/tests/dao/proposals/aibtc-bank-account-set-withdrawal-period.test.ts b/tests/dao/proposals/aibtc-bank-account-set-withdrawal-period.test.ts index d465e952..f81e7cbd 100644 --- a/tests/dao/proposals/aibtc-bank-account-set-withdrawal-period.test.ts +++ b/tests/dao/proposals/aibtc-bank-account-set-withdrawal-period.test.ts @@ -1,7 +1,22 @@ +import { Cl } from "@stacks/transactions"; import { describe, expect, it } from "vitest"; +import { BankAccountErrCode } from "../../error-codes"; -describe("aibtc-bank-account-set-withdrawal-period", () => { - it("should have tests written", () => { - expect(true).toBe(true); +const accounts = simnet.getAccounts(); +const deployer = accounts.get("deployer")!; +const contractName = "aibtc-bank-account-set-withdrawal-period"; +const contractAddress = `${deployer}.${contractName}`; + +const expectedErr = Cl.uint(BankAccountErrCode.ERR_UNAUTHORIZED); + +describe(`core proposal: ${contractName}`, () => { + it("execute() fails if called directly", () => { + const receipt = simnet.callPublicFn( + contractAddress, + "execute", + [Cl.principal(deployer)], + deployer + ); + expect(receipt.result).toBeErr(expectedErr); }); }); diff --git a/tests/dao/proposals/aibtc-bank-account-withdraw-stx.test.ts b/tests/dao/proposals/aibtc-bank-account-withdraw-stx.test.ts index 30346a33..04914d15 100644 --- a/tests/dao/proposals/aibtc-bank-account-withdraw-stx.test.ts +++ b/tests/dao/proposals/aibtc-bank-account-withdraw-stx.test.ts @@ -1,7 +1,22 @@ +import { Cl } from "@stacks/transactions"; import { describe, expect, it } from "vitest"; +import { BankAccountErrCode } from "../../error-codes"; -describe("aibtc-bank-account-withdraw-stx", () => { - it("should have tests written", () => { - expect(true).toBe(true); +const accounts = simnet.getAccounts(); +const deployer = accounts.get("deployer")!; +const contractName = "aibtc-bank-account-withdraw-stx"; +const contractAddress = `${deployer}.${contractName}`; + +const expectedErr = Cl.uint(BankAccountErrCode.ERR_UNAUTHORIZED); + +describe(`core proposal: ${contractName}`, () => { + it("execute() fails if called directly", () => { + const receipt = simnet.callPublicFn( + contractAddress, + "execute", + [Cl.principal(deployer)], + deployer + ); + expect(receipt.result).toBeErr(expectedErr); }); }); diff --git a/tests/dao/proposals/aibtc-base-add-new-extension.test.ts b/tests/dao/proposals/aibtc-base-add-new-extension.test.ts index 7f13dfd6..73db0a4b 100644 --- a/tests/dao/proposals/aibtc-base-add-new-extension.test.ts +++ b/tests/dao/proposals/aibtc-base-add-new-extension.test.ts @@ -1,7 +1,22 @@ +import { Cl } from "@stacks/transactions"; import { describe, expect, it } from "vitest"; +import { BaseDaoErrCode } from "../../error-codes"; -describe("aibtc-base-add-new-extension", () => { - it("should have tests written", () => { - expect(true).toBe(true); +const accounts = simnet.getAccounts(); +const deployer = accounts.get("deployer")!; +const contractName = "aibtc-base-add-new-extension"; +const contractAddress = `${deployer}.${contractName}`; + +const expectedErr = Cl.uint(BaseDaoErrCode.ERR_UNAUTHORIZED); + +describe(`core proposal: ${contractName}`, () => { + it("execute() fails if called directly", () => { + const receipt = simnet.callPublicFn( + contractAddress, + "execute", + [Cl.principal(deployer)], + deployer + ); + expect(receipt.result).toBeErr(expectedErr); }); }); diff --git a/tests/dao/proposals/aibtc-base-bootstrap-initialization.test.ts b/tests/dao/proposals/aibtc-base-bootstrap-initialization.test.ts index 6423498a..72ca347a 100644 --- a/tests/dao/proposals/aibtc-base-bootstrap-initialization.test.ts +++ b/tests/dao/proposals/aibtc-base-bootstrap-initialization.test.ts @@ -1,18 +1,30 @@ import { Cl } from "@stacks/transactions"; import { describe, expect, it } from "vitest"; +import { BaseDaoErrCode } from "../../error-codes"; const accounts = simnet.getAccounts(); const address1 = accounts.get("wallet_1")!; const address2 = accounts.get("wallet_2")!; const deployer = accounts.get("deployer")!; -const contractAddress = `${deployer}.aibtc-base-bootstrap-initialization`; +const contractName = "aibtc-base-bootstrap-initialization"; +const contractAddress = `${deployer}.${contractName}`; + +const expectedErr = Cl.uint(BaseDaoErrCode.ERR_UNAUTHORIZED); const daoManifest = "This is where the DAO can put it's mission, purpose, and goals."; -describe("aibtc-base-bootstrap-proposal", () => { - // Manifest Tests +describe(`core proposal: ${contractName}`, () => { + it("execute() fails if called directly", () => { + const receipt = simnet.callPublicFn( + contractAddress, + "execute", + [Cl.principal(deployer)], + deployer + ); + expect(receipt.result).toBeErr(expectedErr); + }); it("get-dao-manifest() returns DAO_MANIFEST as string", () => { const receipt = simnet.callReadOnlyFn( contractAddress, diff --git a/tests/dao/proposals/aibtc-base-disable-extension.test.ts b/tests/dao/proposals/aibtc-base-disable-extension.test.ts index 8483c8b1..98608709 100644 --- a/tests/dao/proposals/aibtc-base-disable-extension.test.ts +++ b/tests/dao/proposals/aibtc-base-disable-extension.test.ts @@ -1,7 +1,23 @@ +import { Cl } from "@stacks/transactions"; import { describe, expect, it } from "vitest"; +import { CoreProposalErrCode } from "../../error-codes"; -describe("aibtc-base-disable-extension", () => { - it("should have tests written", () => { - expect(true).toBe(true); +const accounts = simnet.getAccounts(); +const deployer = accounts.get("deployer")!; +const contractName = "aibtc-base-disable-extension"; +const contractAddress = `${deployer}.${contractName}`; + +// custom error because proposal is not found / setup yet +const expectedErr = Cl.uint(CoreProposalErrCode.ERR_PROPOSAL_NOT_FOUND); + +describe(`core proposal: ${contractName}`, () => { + it("execute() fails if called directly", () => { + const receipt = simnet.callPublicFn( + contractAddress, + "execute", + [Cl.principal(deployer)], + deployer + ); + expect(receipt.result).toBeErr(expectedErr); }); }); diff --git a/tests/dao/proposals/aibtc-base-enable-extension.test.ts b/tests/dao/proposals/aibtc-base-enable-extension.test.ts index e0a57c83..6c1e1351 100644 --- a/tests/dao/proposals/aibtc-base-enable-extension.test.ts +++ b/tests/dao/proposals/aibtc-base-enable-extension.test.ts @@ -1,7 +1,23 @@ +import { Cl } from "@stacks/transactions"; import { describe, expect, it } from "vitest"; +import { CoreProposalErrCode } from "../../error-codes"; -describe("aibtc-base-enable-extension", () => { - it("should have tests written", () => { - expect(true).toBe(true); +const accounts = simnet.getAccounts(); +const deployer = accounts.get("deployer")!; +const contractName = "aibtc-base-enable-extension"; +const contractAddress = `${deployer}.${contractName}`; + +// custom error because proposal is not found / setup yet +const expectedErr = Cl.uint(CoreProposalErrCode.ERR_PROPOSAL_NOT_FOUND); + +describe(`core proposal: ${contractName}`, () => { + it("execute() fails if called directly", () => { + const receipt = simnet.callPublicFn( + contractAddress, + "execute", + [Cl.principal(deployer)], + deployer + ); + expect(receipt.result).toBeErr(expectedErr); }); }); diff --git a/tests/dao/proposals/aibtc-base-replace-extension.test.ts b/tests/dao/proposals/aibtc-base-replace-extension.test.ts index 9f946aa8..38452128 100644 --- a/tests/dao/proposals/aibtc-base-replace-extension.test.ts +++ b/tests/dao/proposals/aibtc-base-replace-extension.test.ts @@ -1,7 +1,23 @@ +import { Cl } from "@stacks/transactions"; import { describe, expect, it } from "vitest"; +import { CoreProposalErrCode } from "../../error-codes"; -describe("aibtc-base-replace-extension", () => { - it("should have tests written", () => { - expect(true).toBe(true); +const accounts = simnet.getAccounts(); +const deployer = accounts.get("deployer")!; +const contractName = "aibtc-base-replace-extension"; +const contractAddress = `${deployer}.${contractName}`; + +// custom error because proposal is not found / setup yet +const expectedErr = Cl.uint(CoreProposalErrCode.ERR_PROPOSAL_NOT_FOUND); + +describe(`core proposal: ${contractName}`, () => { + it("execute() fails if called directly before dao is initialized", () => { + const receipt = simnet.callPublicFn( + contractAddress, + "execute", + [Cl.principal(deployer)], + deployer + ); + expect(receipt.result).toBeErr(expectedErr); }); }); diff --git a/tests/dao/proposals/aibtc-onchain-messaging-send.test.ts b/tests/dao/proposals/aibtc-onchain-messaging-send.test.ts index 0f7ae9b4..f3bcff91 100644 --- a/tests/dao/proposals/aibtc-onchain-messaging-send.test.ts +++ b/tests/dao/proposals/aibtc-onchain-messaging-send.test.ts @@ -1,7 +1,22 @@ +import { Cl } from "@stacks/transactions"; import { describe, expect, it } from "vitest"; +import { OnchainMessagingErrCode } from "../../error-codes"; -describe("aibtc-onchain-messaging-send", () => { - it("should have tests written", () => { - expect(true).toBe(true); +const accounts = simnet.getAccounts(); +const deployer = accounts.get("deployer")!; +const contractName = "aibtc-onchain-messaging-send"; +const contractAddress = `${deployer}.${contractName}`; + +const expectedErr = Cl.uint(OnchainMessagingErrCode.ERR_UNAUTHORIZED); + +describe(`core proposal: ${contractName}`, () => { + it("execute() fails if called directly", () => { + const receipt = simnet.callPublicFn( + contractAddress, + "execute", + [Cl.principal(deployer)], + deployer + ); + expect(receipt.result).toBeErr(expectedErr); }); }); diff --git a/tests/dao/proposals/aibtc-payments-invoices-add-resource.test.ts b/tests/dao/proposals/aibtc-payments-invoices-add-resource.test.ts index 6c25ec12..5d33e9b9 100644 --- a/tests/dao/proposals/aibtc-payments-invoices-add-resource.test.ts +++ b/tests/dao/proposals/aibtc-payments-invoices-add-resource.test.ts @@ -1,7 +1,22 @@ +import { Cl } from "@stacks/transactions"; import { describe, expect, it } from "vitest"; +import { PaymentsInvoicesErrCode } from "../../error-codes"; -describe("aibtc-payments-invoices-add-resource", () => { - it("should have tests written", () => { - expect(true).toBe(true); +const accounts = simnet.getAccounts(); +const deployer = accounts.get("deployer")!; +const contractName = "aibtc-payments-invoices-add-resource"; +const contractAddress = `${deployer}.${contractName}`; + +const expectedErr = Cl.uint(PaymentsInvoicesErrCode.ERR_UNAUTHORIZED); + +describe(`core proposal: ${contractName}`, () => { + it("execute() fails if called directly", () => { + const receipt = simnet.callPublicFn( + contractAddress, + "execute", + [Cl.principal(deployer)], + deployer + ); + expect(receipt.result).toBeErr(expectedErr); }); }); diff --git a/tests/dao/proposals/aibtc-payments-invoices-pay-invoice-by-resource-name.test.ts b/tests/dao/proposals/aibtc-payments-invoices-pay-invoice-by-resource-name.test.ts index 304694c8..f367aa96 100644 --- a/tests/dao/proposals/aibtc-payments-invoices-pay-invoice-by-resource-name.test.ts +++ b/tests/dao/proposals/aibtc-payments-invoices-pay-invoice-by-resource-name.test.ts @@ -1,7 +1,22 @@ +import { Cl } from "@stacks/transactions"; import { describe, expect, it } from "vitest"; +import { PaymentsInvoicesErrCode } from "../../error-codes"; -describe("aibtc-payments-invoices-pay-invoice-by-resource-name", () => { - it("should have tests written", () => { - expect(true).toBe(true); +const accounts = simnet.getAccounts(); +const deployer = accounts.get("deployer")!; +const contractName = "aibtc-payments-invoices-pay-invoice-by-resource-name"; +const contractAddress = `${deployer}.${contractName}`; + +const expectedErr = Cl.uint(PaymentsInvoicesErrCode.ERR_RESOURCE_NOT_FOUND); + +describe(`core proposal: ${contractName}`, () => { + it("execute() fails if called directly", () => { + const receipt = simnet.callPublicFn( + contractAddress, + "execute", + [Cl.principal(deployer)], + deployer + ); + expect(receipt.result).toBeErr(expectedErr); }); }); diff --git a/tests/dao/proposals/aibtc-payments-invoices-pay-invoice.test.ts b/tests/dao/proposals/aibtc-payments-invoices-pay-invoice.test.ts index 19ee4f14..4d8acbba 100644 --- a/tests/dao/proposals/aibtc-payments-invoices-pay-invoice.test.ts +++ b/tests/dao/proposals/aibtc-payments-invoices-pay-invoice.test.ts @@ -1,7 +1,22 @@ +import { Cl } from "@stacks/transactions"; import { describe, expect, it } from "vitest"; +import { PaymentsInvoicesErrCode } from "../../error-codes"; -describe("aibtc-payments-invoices-pay-invoice", () => { - it("should have tests written", () => { - expect(true).toBe(true); +const accounts = simnet.getAccounts(); +const deployer = accounts.get("deployer")!; +const contractName = "aibtc-payments-invoices-pay-invoice"; +const contractAddress = `${deployer}.${contractName}`; + +const expectedErr = Cl.uint(PaymentsInvoicesErrCode.ERR_RESOURCE_NOT_FOUND); + +describe(`core proposal: ${contractName}`, () => { + it("execute() fails if called directly", () => { + const receipt = simnet.callPublicFn( + contractAddress, + "execute", + [Cl.principal(deployer)], + deployer + ); + expect(receipt.result).toBeErr(expectedErr); }); }); diff --git a/tests/dao/proposals/aibtc-payments-invoices-set-payment-address.test.ts b/tests/dao/proposals/aibtc-payments-invoices-set-payment-address.test.ts index dfdaa103..80ff62df 100644 --- a/tests/dao/proposals/aibtc-payments-invoices-set-payment-address.test.ts +++ b/tests/dao/proposals/aibtc-payments-invoices-set-payment-address.test.ts @@ -1,7 +1,22 @@ +import { Cl } from "@stacks/transactions"; import { describe, expect, it } from "vitest"; +import { PaymentsInvoicesErrCode } from "../../error-codes"; -describe("aibtc-payments-invoices-set-payment-address", () => { - it("should have tests written", () => { - expect(true).toBe(true); +const accounts = simnet.getAccounts(); +const deployer = accounts.get("deployer")!; +const contractName = "aibtc-payments-invoices-set-payment-address"; +const contractAddress = `${deployer}.${contractName}`; + +const expectedErr = Cl.uint(PaymentsInvoicesErrCode.ERR_UNAUTHORIZED); + +describe(`core proposal: ${contractName}`, () => { + it("execute() fails if called directly", () => { + const receipt = simnet.callPublicFn( + contractAddress, + "execute", + [Cl.principal(deployer)], + deployer + ); + expect(receipt.result).toBeErr(expectedErr); }); }); diff --git a/tests/dao/proposals/aibtc-payments-invoices-toggle-resource-by-name.test.ts b/tests/dao/proposals/aibtc-payments-invoices-toggle-resource-by-name.test.ts index c59f3da8..a2841518 100644 --- a/tests/dao/proposals/aibtc-payments-invoices-toggle-resource-by-name.test.ts +++ b/tests/dao/proposals/aibtc-payments-invoices-toggle-resource-by-name.test.ts @@ -1,7 +1,22 @@ +import { Cl } from "@stacks/transactions"; import { describe, expect, it } from "vitest"; +import { PaymentsInvoicesErrCode } from "../../error-codes"; -describe("aibtc-payments-invoices-toggle-resource-by-name", () => { - it("should have tests written", () => { - expect(true).toBe(true); +const accounts = simnet.getAccounts(); +const deployer = accounts.get("deployer")!; +const contractName = "aibtc-payments-invoices-toggle-resource-by-name"; +const contractAddress = `${deployer}.${contractName}`; + +const expectedErr = Cl.uint(PaymentsInvoicesErrCode.ERR_RESOURCE_NOT_FOUND); + +describe(`core proposal: ${contractName}`, () => { + it("execute() fails if called directly", () => { + const receipt = simnet.callPublicFn( + contractAddress, + "execute", + [Cl.principal(deployer)], + deployer + ); + expect(receipt.result).toBeErr(expectedErr); }); }); diff --git a/tests/dao/proposals/aibtc-payments-invoices-toggle-resource.test.ts b/tests/dao/proposals/aibtc-payments-invoices-toggle-resource.test.ts index f0b5786f..f87b7a51 100644 --- a/tests/dao/proposals/aibtc-payments-invoices-toggle-resource.test.ts +++ b/tests/dao/proposals/aibtc-payments-invoices-toggle-resource.test.ts @@ -1,7 +1,22 @@ +import { Cl } from "@stacks/transactions"; import { describe, expect, it } from "vitest"; +import { PaymentsInvoicesErrCode } from "../../error-codes"; -describe("aibtc-payments-invoices-toggle-resource", () => { - it("should have tests written", () => { - expect(true).toBe(true); +const accounts = simnet.getAccounts(); +const deployer = accounts.get("deployer")!; +const contractName = "aibtc-payments-invoices-toggle-resource"; +const contractAddress = `${deployer}.${contractName}`; + +const expectedErr = Cl.uint(PaymentsInvoicesErrCode.ERR_RESOURCE_NOT_FOUND); + +describe(`core proposal: ${contractName}`, () => { + it("execute() fails if called directly", () => { + const receipt = simnet.callPublicFn( + contractAddress, + "execute", + [Cl.principal(deployer)], + deployer + ); + expect(receipt.result).toBeErr(expectedErr); }); }); diff --git a/tests/dao/proposals/aibtc-token-owner-set-token-uri.test.ts b/tests/dao/proposals/aibtc-token-owner-set-token-uri.test.ts index 41e6818d..744173be 100644 --- a/tests/dao/proposals/aibtc-token-owner-set-token-uri.test.ts +++ b/tests/dao/proposals/aibtc-token-owner-set-token-uri.test.ts @@ -1,7 +1,22 @@ +import { Cl } from "@stacks/transactions"; import { describe, expect, it } from "vitest"; +import { TokenOwnerErrCode } from "../../error-codes"; -describe("aibtc-token-owner-set-token-uri", () => { - it("should have tests written", () => { - expect(true).toBe(true); +const accounts = simnet.getAccounts(); +const deployer = accounts.get("deployer")!; +const contractName = "aibtc-token-owner-set-token-uri"; +const contractAddress = `${deployer}.${contractName}`; + +const expectedErr = Cl.uint(TokenOwnerErrCode.ERR_UNAUTHORIZED); + +describe(`core proposal: ${contractName}`, () => { + it("execute() fails if called directly", () => { + const receipt = simnet.callPublicFn( + contractAddress, + "execute", + [Cl.principal(deployer)], + deployer + ); + expect(receipt.result).toBeErr(expectedErr); }); }); diff --git a/tests/dao/proposals/aibtc-token-owner-transfer-ownership.test.ts b/tests/dao/proposals/aibtc-token-owner-transfer-ownership.test.ts index 22af3ff2..dadf6dfe 100644 --- a/tests/dao/proposals/aibtc-token-owner-transfer-ownership.test.ts +++ b/tests/dao/proposals/aibtc-token-owner-transfer-ownership.test.ts @@ -1,7 +1,22 @@ +import { Cl } from "@stacks/transactions"; import { describe, expect, it } from "vitest"; +import { TokenOwnerErrCode } from "../../error-codes"; -describe("aibtc-token-owner-transfer-ownership", () => { - it("should have tests written", () => { - expect(true).toBe(true); +const accounts = simnet.getAccounts(); +const deployer = accounts.get("deployer")!; +const contractName = "aibtc-token-owner-transfer-ownership"; +const contractAddress = `${deployer}.${contractName}`; + +const expectedErr = Cl.uint(TokenOwnerErrCode.ERR_UNAUTHORIZED); + +describe(`core proposal: ${contractName}`, () => { + it("execute() fails if called directly", () => { + const receipt = simnet.callPublicFn( + contractAddress, + "execute", + [Cl.principal(deployer)], + deployer + ); + expect(receipt.result).toBeErr(expectedErr); }); }); diff --git a/tests/dao/proposals/aibtc-treasury-allow-asset.test.ts b/tests/dao/proposals/aibtc-treasury-allow-asset.test.ts index 89ec4cb2..b48669c4 100644 --- a/tests/dao/proposals/aibtc-treasury-allow-asset.test.ts +++ b/tests/dao/proposals/aibtc-treasury-allow-asset.test.ts @@ -1,7 +1,22 @@ +import { Cl } from "@stacks/transactions"; import { describe, expect, it } from "vitest"; +import { TreasuryErrCode } from "../../error-codes"; -describe("aibtc-treasury-allow-asset", () => { - it("should have tests written", () => { - expect(true).toBe(true); +const accounts = simnet.getAccounts(); +const deployer = accounts.get("deployer")!; +const contractName = "aibtc-treasury-allow-asset"; +const contractAddress = `${deployer}.${contractName}`; + +const expectedErr = Cl.uint(TreasuryErrCode.ERR_UNAUTHORIZED); + +describe(`core proposal: ${contractName}`, () => { + it("execute() fails if called directly", () => { + const receipt = simnet.callPublicFn( + contractAddress, + "execute", + [Cl.principal(deployer)], + deployer + ); + expect(receipt.result).toBeErr(expectedErr); }); }); diff --git a/tests/dao/proposals/aibtc-treasury-delegate-stx.test.ts b/tests/dao/proposals/aibtc-treasury-delegate-stx.test.ts index 26c9a164..41e86288 100644 --- a/tests/dao/proposals/aibtc-treasury-delegate-stx.test.ts +++ b/tests/dao/proposals/aibtc-treasury-delegate-stx.test.ts @@ -1,7 +1,22 @@ +import { Cl } from "@stacks/transactions"; import { describe, expect, it } from "vitest"; +import { TreasuryErrCode } from "../../error-codes"; -describe("aibtc-treasury-delegate-stx", () => { - it("should have tests written", () => { - expect(true).toBe(true); +const accounts = simnet.getAccounts(); +const deployer = accounts.get("deployer")!; +const contractName = "aibtc-treasury-delegate-stx"; +const contractAddress = `${deployer}.${contractName}`; + +const expectedErr = Cl.uint(TreasuryErrCode.ERR_UNAUTHORIZED); + +describe(`core proposal: ${contractName}`, () => { + it("execute() fails if called directly", () => { + const receipt = simnet.callPublicFn( + contractAddress, + "execute", + [Cl.principal(deployer)], + deployer + ); + expect(receipt.result).toBeErr(expectedErr); }); }); diff --git a/tests/dao/proposals/aibtc-treasury-deposit-ft.test.ts b/tests/dao/proposals/aibtc-treasury-deposit-ft.test.ts index d856a720..acacfa16 100644 --- a/tests/dao/proposals/aibtc-treasury-deposit-ft.test.ts +++ b/tests/dao/proposals/aibtc-treasury-deposit-ft.test.ts @@ -1,7 +1,22 @@ +import { Cl } from "@stacks/transactions"; import { describe, expect, it } from "vitest"; +import { TreasuryErrCode } from "../../error-codes"; -describe("aibtc-treasury-deposit-ft", () => { - it("should have tests written", () => { - expect(true).toBe(true); +const accounts = simnet.getAccounts(); +const deployer = accounts.get("deployer")!; +const contractName = "aibtc-treasury-deposit-ft"; +const contractAddress = `${deployer}.${contractName}`; + +const expectedErr = Cl.uint(TreasuryErrCode.ERR_UNKNOWN_ASSSET); + +describe(`core proposal: ${contractName}`, () => { + it("execute() fails if called directly", () => { + const receipt = simnet.callPublicFn( + contractAddress, + "execute", + [Cl.principal(deployer)], + deployer + ); + expect(receipt.result).toBeErr(expectedErr); }); }); diff --git a/tests/dao/proposals/aibtc-treasury-deposit-nft.test.ts b/tests/dao/proposals/aibtc-treasury-deposit-nft.test.ts index 7c50a64a..89479fe6 100644 --- a/tests/dao/proposals/aibtc-treasury-deposit-nft.test.ts +++ b/tests/dao/proposals/aibtc-treasury-deposit-nft.test.ts @@ -1,7 +1,22 @@ +import { Cl } from "@stacks/transactions"; import { describe, expect, it } from "vitest"; +import { TreasuryErrCode } from "../../error-codes"; -describe("aibtc-treasury-deposit-nft", () => { - it("should have tests written", () => { - expect(true).toBe(true); +const accounts = simnet.getAccounts(); +const deployer = accounts.get("deployer")!; +const contractName = "aibtc-treasury-deposit-nft"; +const contractAddress = `${deployer}.${contractName}`; + +const expectedErr = Cl.uint(TreasuryErrCode.ERR_UNKNOWN_ASSSET); + +describe(`core proposal: ${contractName}`, () => { + it("execute() fails if called directly", () => { + const receipt = simnet.callPublicFn( + contractAddress, + "execute", + [Cl.principal(deployer)], + deployer + ); + expect(receipt.result).toBeErr(expectedErr); }); }); diff --git a/tests/dao/proposals/aibtc-treasury-deposit-stx.test.ts b/tests/dao/proposals/aibtc-treasury-deposit-stx.test.ts index 98bf26d8..605101b3 100644 --- a/tests/dao/proposals/aibtc-treasury-deposit-stx.test.ts +++ b/tests/dao/proposals/aibtc-treasury-deposit-stx.test.ts @@ -1,7 +1,20 @@ +import { Cl } from "@stacks/transactions"; import { describe, expect, it } from "vitest"; +import { ErrCode } from "../extensions/aibtc-treasury.test"; -describe("aibtc-treasury-deposit-stx", () => { - it("should have tests written", () => { - expect(true).toBe(true); +const accounts = simnet.getAccounts(); +const deployer = accounts.get("deployer")!; +const contractName = "aibtc-treasury-deposit-stx"; +const contractAddress = `${deployer}.${contractName}`; + +describe(`core proposal: ${contractName}`, () => { + it("execute() succeeds if called directly (open to anyone)", () => { + const receipt = simnet.callPublicFn( + contractAddress, + "execute", + [Cl.principal(deployer)], + deployer + ); + expect(receipt.result).toBeOk(Cl.bool(true)); }); }); diff --git a/tests/dao/proposals/aibtc-treasury-freeze-asset.test.ts b/tests/dao/proposals/aibtc-treasury-freeze-asset.test.ts index 71e07733..d75a246a 100644 --- a/tests/dao/proposals/aibtc-treasury-freeze-asset.test.ts +++ b/tests/dao/proposals/aibtc-treasury-freeze-asset.test.ts @@ -1,7 +1,22 @@ +import { Cl } from "@stacks/transactions"; import { describe, expect, it } from "vitest"; +import { TreasuryErrCode } from "../../error-codes"; -describe("aibtc-treasury-freeze-asset", () => { - it("should have tests written", () => { - expect(true).toBe(true); +const accounts = simnet.getAccounts(); +const deployer = accounts.get("deployer")!; +const contractName = "aibtc-treasury-freeze-asset"; +const contractAddress = `${deployer}.${contractName}`; + +const expectedErr = Cl.uint(TreasuryErrCode.ERR_UNAUTHORIZED); + +describe(`core proposal: ${contractName}`, () => { + it("execute() fails if called directly", () => { + const receipt = simnet.callPublicFn( + contractAddress, + "execute", + [Cl.principal(deployer)], + deployer + ); + expect(receipt.result).toBeErr(expectedErr); }); }); diff --git a/tests/dao/proposals/aibtc-treasury-revoke-delegation.test.ts b/tests/dao/proposals/aibtc-treasury-revoke-delegation.test.ts index 1f1fabb1..f6ec4dbc 100644 --- a/tests/dao/proposals/aibtc-treasury-revoke-delegation.test.ts +++ b/tests/dao/proposals/aibtc-treasury-revoke-delegation.test.ts @@ -1,7 +1,22 @@ +import { Cl } from "@stacks/transactions"; import { describe, expect, it } from "vitest"; +import { TreasuryErrCode } from "../../error-codes"; -describe("aibtc-treasury-revoke-delegation", () => { - it("should have tests written", () => { - expect(true).toBe(true); +const accounts = simnet.getAccounts(); +const deployer = accounts.get("deployer")!; +const contractName = "aibtc-treasury-revoke-delegation"; +const contractAddress = `${deployer}.${contractName}`; + +const expectedErr = Cl.uint(TreasuryErrCode.ERR_UNAUTHORIZED); + +describe(`core proposal: ${contractName}`, () => { + it("execute() fails if called directly", () => { + const receipt = simnet.callPublicFn( + contractAddress, + "execute", + [Cl.principal(deployer)], + deployer + ); + expect(receipt.result).toBeErr(expectedErr); }); }); diff --git a/tests/dao/proposals/aibtc-treasury-withdraw-ft.test.ts b/tests/dao/proposals/aibtc-treasury-withdraw-ft.test.ts index 49fa8a90..e455e930 100644 --- a/tests/dao/proposals/aibtc-treasury-withdraw-ft.test.ts +++ b/tests/dao/proposals/aibtc-treasury-withdraw-ft.test.ts @@ -1,7 +1,22 @@ +import { Cl } from "@stacks/transactions"; import { describe, expect, it } from "vitest"; +import { TreasuryErrCode } from "../../error-codes"; -describe("aibtc-treasury-withdraw-ft", () => { - it("should have tests written", () => { - expect(true).toBe(true); +const accounts = simnet.getAccounts(); +const deployer = accounts.get("deployer")!; +const contractName = "aibtc-treasury-withdraw-ft"; +const contractAddress = `${deployer}.${contractName}`; + +const expectedErr = Cl.uint(TreasuryErrCode.ERR_UNAUTHORIZED); + +describe(`core proposal: ${contractName}`, () => { + it("execute() fails if called directly", () => { + const receipt = simnet.callPublicFn( + contractAddress, + "execute", + [Cl.principal(deployer)], + deployer + ); + expect(receipt.result).toBeErr(expectedErr); }); }); diff --git a/tests/dao/proposals/aibtc-treasury-withdraw-nft.test.ts b/tests/dao/proposals/aibtc-treasury-withdraw-nft.test.ts index af5a2ed9..4ed1db17 100644 --- a/tests/dao/proposals/aibtc-treasury-withdraw-nft.test.ts +++ b/tests/dao/proposals/aibtc-treasury-withdraw-nft.test.ts @@ -1,7 +1,22 @@ +import { Cl } from "@stacks/transactions"; import { describe, expect, it } from "vitest"; +import { TreasuryErrCode } from "../../error-codes"; -describe("aibtc-treasury-withdraw-nft", () => { - it("should have tests written", () => { - expect(true).toBe(true); +const accounts = simnet.getAccounts(); +const deployer = accounts.get("deployer")!; +const contractName = "aibtc-treasury-withdraw-nft"; +const contractAddress = `${deployer}.${contractName}`; + +const expectedErr = Cl.uint(TreasuryErrCode.ERR_UNAUTHORIZED); + +describe(`core proposal: ${contractName}`, () => { + it("execute() fails if called directly", () => { + const receipt = simnet.callPublicFn( + contractAddress, + "execute", + [Cl.principal(deployer)], + deployer + ); + expect(receipt.result).toBeErr(expectedErr); }); }); diff --git a/tests/dao/proposals/aibtc-treasury-withdraw-stx.test.ts b/tests/dao/proposals/aibtc-treasury-withdraw-stx.test.ts index 86562314..500e626d 100644 --- a/tests/dao/proposals/aibtc-treasury-withdraw-stx.test.ts +++ b/tests/dao/proposals/aibtc-treasury-withdraw-stx.test.ts @@ -1,7 +1,22 @@ +import { Cl } from "@stacks/transactions"; import { describe, expect, it } from "vitest"; +import { TreasuryErrCode } from "../../error-codes"; -describe("aibtc-treasury-withdraw-stx", () => { - it("should have tests written", () => { - expect(true).toBe(true); +const accounts = simnet.getAccounts(); +const deployer = accounts.get("deployer")!; +const contractName = "aibtc-treasury-withdraw-stx"; +const contractAddress = `${deployer}.${contractName}`; + +const expectedErr = Cl.uint(TreasuryErrCode.ERR_UNAUTHORIZED); + +describe(`core proposal: ${contractName}`, () => { + it("execute() fails if called directly", () => { + const receipt = simnet.callPublicFn( + contractAddress, + "execute", + [Cl.principal(deployer)], + deployer + ); + expect(receipt.result).toBeErr(expectedErr); }); }); diff --git a/tests/error-codes.ts b/tests/error-codes.ts new file mode 100644 index 00000000..9dd70068 --- /dev/null +++ b/tests/error-codes.ts @@ -0,0 +1,80 @@ +export enum BaseDaoErrCode { + ERR_UNAUTHORIZED = 900, + ERR_ALREADY_EXECUTED, + ERR_INVALID_EXTENSION, + ERR_NO_EMPTY_LISTS, +} + +export enum ActionProposalsErrCode { + ERR_NOT_DAO_OR_EXTENSION = 1000, + ERR_INSUFFICIENT_BALANCE, + ERR_FETCHING_TOKEN_DATA, + ERR_PROPOSAL_NOT_FOUND, + ERR_PROPOSAL_STILL_ACTIVE, + ERR_SAVING_PROPOSAL, + ERR_PROPOSAL_ALREADY_CONCLUDED, + ERR_RETRIEVING_START_BLOCK_HASH, + ERR_VOTE_TOO_SOON, + ERR_VOTE_TOO_LATE, + ERR_ALREADY_VOTED, + ERR_INVALID_ACTION, +} + +export enum ActionErrCode { + ERR_UNAUTHORIZED = 10001, + ERR_INVALID_PARAMS, +} + +export enum BankAccountErrCode { + ERR_INVALID = 2000, + ERR_UNAUTHORIZED, + ERR_TOO_SOON, + ERR_INVALID_AMOUNT, +} + +export enum CoreProposalErrCode { + ERR_NOT_DAO_OR_EXTENSION = 3000, + ERR_FETCHING_TOKEN_DATA, + ERR_INSUFFICIENT_BALANCE, + ERR_PROPOSAL_NOT_FOUND, + ERR_PROPOSAL_ALREADY_EXECUTED, + ERR_PROPOSAL_STILL_ACTIVE, + ERR_SAVING_PROPOSAL, + ERR_PROPOSAL_ALREADY_CONCLUDED, + ERR_RETRIEVING_START_BLOCK_HASH, + ERR_VOTE_TOO_SOON, + ERR_VOTE_TOO_LATE, + ERR_ALREADY_VOTED, + ERR_FIRST_VOTING_PERIOD, +} + +export enum OnchainMessagingErrCode { + INPUT_ERROR = 4000, + ERR_UNAUTHORIZED, +} + +export enum PaymentsInvoicesErrCode { + ERR_UNAUTHORIZED = 5000, + ERR_INVALID_PARAMS, + ERR_NAME_ALREADY_USED, + ERR_SAVING_RESOURCE_DATA, + ERR_DELETING_RESOURCE_DATA, + ERR_RESOURCE_NOT_FOUND, + ERR_RESOURCE_DISABLED, + ERR_USER_ALREADY_EXISTS, + ERR_SAVING_USER_DATA, + ERR_USER_NOT_FOUND, + ERR_INVOICE_ALREADY_PAID, + ERR_SAVING_INVOICE_DATA, + ERR_INVOICE_NOT_FOUND, + ERR_RECENT_PAYMENT_NOT_FOUND, +} + +export enum TreasuryErrCode { + ERR_UNAUTHORIZED = 6000, + ERR_UNKNOWN_ASSSET, +} + +export enum TokenOwnerErrCode { + ERR_UNAUTHORIZED = 7000, +} diff --git a/tests/test-utilities.ts b/tests/test-utilities.ts index e69de29b..8a9e5b6a 100644 --- a/tests/test-utilities.ts +++ b/tests/test-utilities.ts @@ -0,0 +1,142 @@ +import { Cl, ClarityValue, cvToValue } from "@stacks/transactions"; +import { expect } from "vitest"; + +export const actionProposalsContractName = "aibtc-action-proposals"; +export const coreProposalsContractName = "aibtc-core-proposals"; +const votingPeriod = 144; // 24 hours + +function getPercentageOfSupply(amount: number, totalSupply: number) { + const rawPercentage = (amount / totalSupply) * 100; + const percentage = rawPercentage.toFixed(2); + return percentage; +} + +export function fundVoters(deployer: string, voters: string[]) { + for (const voter of voters) { + const stxAmount = Math.floor(Math.random() * 500000000) + 1000000; + const getDaoTokensReceipt = getDaoTokens(deployer, voter, stxAmount); + const getAddressBalanceResult = simnet.callReadOnlyFn( + `${deployer}.aibtc-token`, + "get-balance", + [Cl.principal(voter)], + deployer + ).result; + const expectedBalance = parseInt(cvToValue(getAddressBalanceResult).value); + expect(getDaoTokensReceipt.result).toBeOk(Cl.uint(expectedBalance)); + } +} + +export function getDaoTokens( + deployer: string, + address: string, + stxAmount: number +) { + const tokenContractName = "aibtc-token"; + const tokenContractAddress = `${deployer}.${tokenContractName}`; + const tokenDexContractName = "aibtc-token-dex"; + const tokenDexContractAddress = `${deployer}.${tokenDexContractName}`; + + const getDaoTokensReceipt = simnet.callPublicFn( + tokenDexContractAddress, + "buy", + [Cl.principal(tokenContractAddress), Cl.uint(stxAmount)], + address + ); + + return getDaoTokensReceipt; +} + +export function constructDao(deployer: string) { + const baseDaoContractName = "aibtcdev-base-dao"; + const baseDaoContractAddress = `${deployer}.${baseDaoContractName}`; + const bootstrapContractName = "aibtc-base-bootstrap-initialization"; + const bootstrapContractAddress = `${deployer}.${bootstrapContractName}`; + + const constructDaoReceipt = simnet.callPublicFn( + baseDaoContractAddress, + "construct", + [Cl.principal(bootstrapContractAddress)], + deployer + ); + + return constructDaoReceipt; +} + +export function passCoreProposal( + proposalContractAddress: string, + deployer: string, + voters: string[] +) { + // create-proposal + const createProposalReceipt = simnet.callPublicFn( + `${deployer}.${coreProposalsContractName}`, + "create-proposal", + [Cl.principal(proposalContractAddress)], + deployer + ); + expect(createProposalReceipt.result).toBeOk(Cl.bool(true)); + // vote-on-proposal + for (const voter of voters) { + const voteReceipt = simnet.callPublicFn( + `${deployer}.${coreProposalsContractName}`, + "vote-on-proposal", + [Cl.principal(proposalContractAddress), Cl.bool(true)], + voter + ); + expect(voteReceipt.result).toBeOk(Cl.bool(true)); + } + // progress past the end block + simnet.mineEmptyBlocks(votingPeriod); + // conclude-proposal + const concludeProposalReceipt = simnet.callPublicFn( + `${deployer}.${coreProposalsContractName}`, + "conclude-proposal", + [Cl.principal(proposalContractAddress)], + deployer + ); + // return final receipt for processing + return concludeProposalReceipt; +} + +export function passActionProposal( + proposalContractAddress: string, + proposalParams: ClarityValue, + deployer: string, + sender: string, + voters: string[] +) { + // TODO: hardcoded + const proposalId = 1; + // propose-action + const proposeActionReceipt = simnet.callPublicFn( + `${deployer}.${actionProposalsContractName}`, + "propose-action", + [ + Cl.principal(proposalContractAddress), + Cl.buffer(Cl.serialize(proposalParams)), + ], + sender + ); + expect(proposeActionReceipt.result).toBeOk(Cl.bool(true)); + // vote-on-proposal + for (const voter of voters) { + const voteReceipt = simnet.callPublicFn( + `${deployer}.${actionProposalsContractName}`, + "vote-on-proposal", + [Cl.uint(proposalId), Cl.bool(true)], + voter + ); + expect(voteReceipt.result).toBeOk(Cl.bool(true)); + } + // progress past the end block + simnet.mineEmptyBlocks(votingPeriod); + // conclude-proposal + const concludeProposalReceipt = simnet.callPublicFn( + `${deployer}.${actionProposalsContractName}`, + "conclude-proposal", + [Cl.uint(proposalId), Cl.principal(proposalContractAddress)], + deployer + ); + // return final receipt for processing + return concludeProposalReceipt; +}