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

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions guardio/.gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
tests/** linguist-vendored
vitest.config.js linguist-vendored
* text=lf
13 changes: 13 additions & 0 deletions guardio/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@

**/settings/Mainnet.toml
**/settings/Testnet.toml
.cache/**
history.txt

logs
*.log
npm-debug.log*
coverage
*.info
costs-reports.json
node_modules
4 changes: 4 additions & 0 deletions guardio/.vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@

{
"files.eol": "\n"
}
19 changes: 19 additions & 0 deletions guardio/.vscode/tasks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@

{
"version": "2.0.0",
"tasks": [
{
"label": "check contracts",
"group": "test",
"type": "shell",
"command": "clarinet check"
},
{
"type": "npm",
"script": "test",
"group": "test",
"problemMatcher": [],
"label": "npm test"
}
]
}
19 changes: 19 additions & 0 deletions guardio/Clarinet.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
[project]
name = 'guardio'
description = ''
authors = []
telemetry = true
cache_dir = '.\.cache'
requirements = []
[contracts.guardio]
path = 'contracts/guardio.clar'
clarity_version = 2
epoch = 2.5
[repl.analysis]
passes = ['check_checker']

[repl.analysis.check_checker]
strict = false
trusted_sender = false
trusted_caller = false
callee_filter = false
96 changes: 96 additions & 0 deletions guardio/contracts/guardio.clar
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
;; Decentralized Insurance Contract

;; Constants
(define-constant contract-admin tx-sender)
(define-constant err-admin-only (err u100))
(define-constant err-invalid-request (err u101))
(define-constant err-insufficient-funds (err u102))
(define-constant err-not-covered (err u103))
(define-constant err-invalid-parameters (err u104))
(define-constant max-protection u1000000000) ;; Maximum coverage amount
(define-constant max-period u52560) ;; Maximum duration (about 1 year in blocks)
(define-constant min-payment u1000) ;; Minimum premium amount

;; Data Maps
(define-map protection-contracts
principal
{
protection-amount: uint,
payment: uint,
termination: uint
})

(define-map protection-requests
principal
{
value: uint,
approved: bool
})

;; Variables
(define-data-var protection-fund uint u0)

;; Admin Functions
(define-public (create-policy (protection-amount uint) (payment uint) (period uint))
(let ((termination (+ block-height period)))
(begin
(asserts! (is-eq tx-sender contract-admin) err-admin-only)
(asserts! (<= protection-amount max-protection) err-invalid-parameters)
(asserts! (>= payment min-payment) err-invalid-parameters)
(asserts! (<= period max-period) err-invalid-parameters)
(map-set protection-contracts tx-sender
{
protection-amount: protection-amount,
payment: payment,
termination: termination
})
(ok true))))

;; User Functions
(define-public (purchase-policy (protection-amount uint) (period uint))
(let
((contract-payment (* protection-amount (/ u1 u100) period))
(termination (+ block-height period)))
(begin
(asserts! (<= protection-amount max-protection) err-invalid-parameters)
(asserts! (<= period max-period) err-invalid-parameters)
(asserts! (>= contract-payment min-payment) err-invalid-parameters)

;; Safe arithmetic operations with checks
(asserts! (>= (+ (var-get protection-fund) contract-payment)
(var-get protection-fund))
err-invalid-parameters)

(try! (stx-transfer? contract-payment tx-sender (as-contract tx-sender)))
(var-set protection-fund (+ (var-get protection-fund) contract-payment))
(map-set protection-contracts tx-sender
{
protection-amount: protection-amount,
payment: contract-payment,
termination: termination
})
(ok true))))

(define-public (file-claim (value uint))
(let
((contract (unwrap! (map-get? protection-contracts tx-sender) (err err-not-covered))))
(begin
(asserts! (<= value (get protection-amount contract)) (err err-invalid-request))
(asserts! (is-ok (as-contract (stx-transfer? value tx-sender tx-sender))) (err err-insufficient-funds))
(var-set protection-fund (- (var-get protection-fund) value))
(map-set protection-requests tx-sender
{
value: value,
approved: true
})
(ok true))))

;; Read-Only Functions
(define-read-only (get-policy-details (holder principal))
(map-get? protection-contracts holder))

(define-read-only (get-claim-details (requester principal))
(map-get? protection-requests requester))

(define-read-only (get-fund-balance)
(var-get protection-fund))
24 changes: 24 additions & 0 deletions guardio/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@

{
"name": "guardio-tests",
"version": "1.0.0",
"description": "Run unit tests on this project.",
"type": "module",
"private": true,
"scripts": {
"test": "vitest run",
"test:report": "vitest run -- --coverage --costs",
"test:watch": "chokidar \"tests/**/*.ts\" \"contracts/**/*.clar\" -c \"npm run test:report\""
},
"author": "",
"license": "ISC",
"dependencies": {
"@hirosystems/clarinet-sdk": "^2.3.2",
"@stacks/transactions": "^6.12.0",
"chokidar-cli": "^3.0.0",
"typescript": "^5.3.3",
"vite": "^5.1.4",
"vitest": "^1.3.1",
"vitest-environment-clarinet": "^2.0.0"
}
}
156 changes: 156 additions & 0 deletions guardio/settings/Devnet.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
[network]
name = "devnet"
deployment_fee_rate = 10

[accounts.deployer]
mnemonic = "twice kind fence tip hidden tilt action fragile skin nothing glory cousin green tomorrow spring wrist shed math olympic multiply hip blue scout claw"
balance = 100_000_000_000_000
# secret_key: 753b7cc01a1a2e86221266a154af739463fce51219d97e4f856cd7200c3bd2a601
# stx_address: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM
# btc_address: mqVnk6NPRdhntvfm4hh9vvjiRkFDUuSYsH

[accounts.wallet_1]
mnemonic = "sell invite acquire kitten bamboo drastic jelly vivid peace spawn twice guilt pave pen trash pretty park cube fragile unaware remain midnight betray rebuild"
balance = 100_000_000_000_000
# secret_key: 7287ba251d44a4d3fd9276c88ce34c5c52a038955511cccaf77e61068649c17801
# stx_address: ST1SJ3DTE5DN7X54YDH5D64R3BCB6A2AG2ZQ8YPD5
# btc_address: mr1iPkD9N3RJZZxXRk7xF9d36gffa6exNC

[accounts.wallet_2]
mnemonic = "hold excess usual excess ring elephant install account glad dry fragile donkey gaze humble truck breeze nation gasp vacuum limb head keep delay hospital"
balance = 100_000_000_000_000
# secret_key: 530d9f61984c888536871c6573073bdfc0058896dc1adfe9a6a10dfacadc209101
# stx_address: ST2CY5V39NHDPWSXMW9QDT3HC3GD6Q6XX4CFRK9AG
# btc_address: muYdXKmX9bByAueDe6KFfHd5Ff1gdN9ErG

[accounts.wallet_3]
mnemonic = "cycle puppy glare enroll cost improve round trend wrist mushroom scorpion tower claim oppose clever elephant dinosaur eight problem before frozen dune wagon high"
balance = 100_000_000_000_000
# secret_key: d655b2523bcd65e34889725c73064feb17ceb796831c0e111ba1a552b0f31b3901
# stx_address: ST2JHG361ZXG51QTKY2NQCVBPPRRE2KZB1HR05NNC
# btc_address: mvZtbibDAAA3WLpY7zXXFqRa3T4XSknBX7

[accounts.wallet_4]
mnemonic = "board list obtain sugar hour worth raven scout denial thunder horse logic fury scorpion fold genuine phrase wealth news aim below celery when cabin"
balance = 100_000_000_000_000
# secret_key: f9d7206a47f14d2870c163ebab4bf3e70d18f5d14ce1031f3902fbbc894fe4c701
# stx_address: ST2NEB84ASENDXKYGJPQW86YXQCEFEX2ZQPG87ND
# btc_address: mg1C76bNTutiCDV3t9nWhZs3Dc8LzUufj8

[accounts.wallet_5]
mnemonic = "hurry aunt blame peanut heavy update captain human rice crime juice adult scale device promote vast project quiz unit note reform update climb purchase"
balance = 100_000_000_000_000
# secret_key: 3eccc5dac8056590432db6a35d52b9896876a3d5cbdea53b72400bc9c2099fe801
# stx_address: ST2REHHS5J3CERCRBEPMGH7921Q6PYKAADT7JP2VB
# btc_address: mweN5WVqadScHdA81aATSdcVr4B6dNokqx

[accounts.wallet_6]
mnemonic = "area desk dutch sign gold cricket dawn toward giggle vibrant indoor bench warfare wagon number tiny universe sand talk dilemma pottery bone trap buddy"
balance = 100_000_000_000_000
# secret_key: 7036b29cb5e235e5fd9b09ae3e8eec4404e44906814d5d01cbca968a60ed4bfb01
# stx_address: ST3AM1A56AK2C1XAFJ4115ZSV26EB49BVQ10MGCS0
# btc_address: mzxXgV6e4BZSsz8zVHm3TmqbECt7mbuErt

[accounts.wallet_7]
mnemonic = "prevent gallery kind limb income control noise together echo rival record wedding sense uncover school version force bleak nuclear include danger skirt enact arrow"
balance = 100_000_000_000_000
# secret_key: b463f0df6c05d2f156393eee73f8016c5372caa0e9e29a901bb7171d90dc4f1401
# stx_address: ST3PF13W7Z0RRM42A8VZRVFQ75SV1K26RXEP8YGKJ
# btc_address: n37mwmru2oaVosgfuvzBwgV2ysCQRrLko7

[accounts.wallet_8]
mnemonic = "female adjust gallery certain visit token during great side clown fitness like hurt clip knife warm bench start reunion globe detail dream depend fortune"
balance = 100_000_000_000_000
# secret_key: 6a1a754ba863d7bab14adbbc3f8ebb090af9e871ace621d3e5ab634e1422885e01
# stx_address: ST3NBRSFKX28FQ2ZJ1MAKX58HKHSDGNV5N7R21XCP
# btc_address: n2v875jbJ4RjBnTjgbfikDfnwsDV5iUByw

[accounts.faucet]
mnemonic = "shadow private easily thought say logic fault paddle word top book during ignore notable orange flight clock image wealth health outside kitten belt reform"
balance = 100_000_000_000_000
# secret_key: de433bdfa14ec43aa1098d5be594c8ffb20a31485ff9de2923b2689471c401b801
# stx_address: STNHKEPYEPJ8ET55ZZ0M5A34J0R3N5FM2CMMMAZ6
# btc_address: mjSrB3wS4xab3kYqFktwBzfTdPg367ZJ2d

[devnet]
disable_stacks_explorer = false
disable_stacks_api = false
# disable_postgres = false
# disable_subnet_api = false
# disable_bitcoin_explorer = true
# working_dir = "tmp/devnet"
# stacks_node_events_observers = ["host.docker.internal:8002"]
# miner_mnemonic = "fragile loan twenty basic net assault jazz absorb diet talk art shock innocent float punch travel gadget embrace caught blossom hockey surround initial reduce"
# miner_derivation_path = "m/44'/5757'/0'/0/0"
# faucet_mnemonic = "shadow private easily thought say logic fault paddle word top book during ignore notable orange flight clock image wealth health outside kitten belt reform"
# faucet_derivation_path = "m/44'/5757'/0'/0/0"
# orchestrator_port = 20445
# bitcoin_node_p2p_port = 18444
# bitcoin_node_rpc_port = 18443
# bitcoin_node_username = "devnet"
# bitcoin_node_password = "devnet"
# bitcoin_controller_block_time = 30_000
# stacks_node_rpc_port = 20443
# stacks_node_p2p_port = 20444
# stacks_api_port = 3999
# stacks_api_events_port = 3700
# bitcoin_explorer_port = 8001
# stacks_explorer_port = 8000
# postgres_port = 5432
# postgres_username = "postgres"
# postgres_password = "postgres"
# postgres_database = "postgres"
# bitcoin_node_image_url = "quay.io/hirosystems/bitcoind:26.0"
# stacks_node_image_url = "quay.io/hirosystems/stacks-node:devnet-2.5"
# stacks_signer_image_url = "quay.io/hirosystems/stacks-signer:devnet-2.5"
# stacks_api_image_url = "hirosystems/stacks-blockchain-api:master"
# stacks_explorer_image_url = "hirosystems/explorer:latest"
# bitcoin_explorer_image_url = "quay.io/hirosystems/bitcoin-explorer:devnet"
# postgres_image_url = "postgres:alpine"
# enable_subnet_node = true
# subnet_node_image_url = "hirosystems/stacks-subnets:0.8.1"
# subnet_leader_mnemonic = "twice kind fence tip hidden tilt action fragile skin nothing glory cousin green tomorrow spring wrist shed math olympic multiply hip blue scout claw"
# subnet_leader_derivation_path = "m/44'/5757'/0'/0/0"
# subnet_contract_id = "ST173JK7NZBA4BS05ZRATQH1K89YJMTGEH1Z5J52E.subnet-v3-0-1"
# subnet_node_rpc_port = 30443
# subnet_node_p2p_port = 30444
# subnet_events_ingestion_port = 30445
# subnet_node_events_observers = ["host.docker.internal:8002"]
# subnet_api_image_url = "hirosystems/stacks-blockchain-api:master"
# subnet_api_postgres_database = "subnet_api"

# epoch_2_0 = 100
# epoch_2_05 = 100
# epoch_2_1 = 101
# epoch_2_2 = 102
# epoch_2_3 = 103
# epoch_2_4 = 104
# epoch_2_5 = 108
# epoch_3_0 = 144


# Send some stacking orders
[[devnet.pox_stacking_orders]]
start_at_cycle = 1
duration = 10
auto_extend = true
wallet = "wallet_1"
slots = 2
btc_address = "mr1iPkD9N3RJZZxXRk7xF9d36gffa6exNC"

[[devnet.pox_stacking_orders]]
start_at_cycle = 1
duration = 10
auto_extend = true
wallet = "wallet_2"
slots = 2
btc_address = "muYdXKmX9bByAueDe6KFfHd5Ff1gdN9ErG"

[[devnet.pox_stacking_orders]]
start_at_cycle = 1
duration = 10
auto_extend = true
wallet = "wallet_3"
slots = 2
btc_address = "mvZtbibDAAA3WLpY7zXXFqRa3T4XSknBX7"

21 changes: 21 additions & 0 deletions guardio/tests/guardio.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@

import { describe, expect, it } from "vitest";

const accounts = simnet.getAccounts();
const address1 = accounts.get("wallet_1")!;

/*
The test below is an example. To learn more, read the testing documentation here:
https://docs.hiro.so/stacks/clarinet-js-sdk
*/

describe("example tests", () => {
it("ensures simnet is well initalised", () => {
expect(simnet.blockHeight).toBeDefined();
});

// it("shows an example", () => {
// const { result } = simnet.callReadOnlyFn("counter", "get-counter", [], address1);
// expect(result).toBeUint(0);
// });
});
26 changes: 26 additions & 0 deletions guardio/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@

{
"compilerOptions": {
"target": "ESNext",
"useDefineForClassFields": true,
"module": "ESNext",
"lib": ["ESNext"],
"skipLibCheck": true,

"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,

"strict": true,
"noImplicitAny": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true
},
"include": [
"node_modules/@hirosystems/clarinet-sdk/vitest-helpers/src",
"tests"
]
}
Loading