Skip to content

Commit 00ebadf

Browse files
committed
feat: add asset insurance and claims management contract
1 parent 57ae447 commit 00ebadf

2 files changed

Lines changed: 193 additions & 0 deletions

File tree

Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
#![allow(clippy::too_many_arguments)]
2+
3+
use soroban_sdk::{
4+
contracttype, Address, BytesN, Env, String, Vec, Map, Symbol, log
5+
};
6+
use crate::{Error, handle_error};
7+
8+
#[contracttype]
9+
#[derive(Clone, Debug, Eq, PartialEq)]
10+
pub enum PolicyStatus {
11+
Active,
12+
Expired,
13+
Cancelled,
14+
Suspended,
15+
}
16+
17+
#[contracttype]
18+
#[derive(Clone, Debug, Eq, PartialEq)]
19+
pub enum ClaimStatus {
20+
Submitted,
21+
UnderReview,
22+
Approved,
23+
Rejected,
24+
Paid,
25+
Disputed,
26+
}
27+
28+
#[contracttype]
29+
#[derive(Clone, Debug, Eq, PartialEq)]
30+
pub enum PolicyType {
31+
Comprehensive,
32+
Theft,
33+
Damage,
34+
Liability,
35+
BusinessInterruption,
36+
}
37+
38+
#[contracttype]
39+
#[derive(Clone, Debug, Eq, PartialEq)]
40+
pub enum ClaimType {
41+
Theft,
42+
Damage,
43+
Loss,
44+
Liability,
45+
Other,
46+
}
47+
48+
#[contracttype]
49+
#[derive(Clone, Debug)]
50+
pub struct InsurancePolicy {
51+
pub policy_id: BytesN<32>,
52+
pub holder: Address,
53+
pub insurer: Address,
54+
pub asset_id: BytesN<32>,
55+
pub coverage_amount: i128,
56+
pub deductible: i128,
57+
pub premium: i128,
58+
pub start_date: u64,
59+
pub end_date: u64,
60+
pub status: PolicyStatus,
61+
pub auto_renew: bool,
62+
pub last_payment: u64,
63+
}
64+
65+
#[contracttype]
66+
#[derive(Clone, Debug)]
67+
pub struct InsuranceClaim {
68+
pub claim_id: BytesN<32>,
69+
pub policy_id: BytesN<32>,
70+
pub asset_id: BytesN<32>,
71+
pub claimant: Address,
72+
pub amount: i128,
73+
pub status: ClaimStatus,
74+
pub filed_at: u64,
75+
pub approved_amount: i128,
76+
}
77+
78+
#[contracttype]
79+
#[derive(Clone)]
80+
pub enum DataKey {
81+
Policy(BytesN<32>),
82+
Claim(BytesN<32>),
83+
AssetPolicies(BytesN<32>),
84+
}
85+
86+
pub fn create_policy(
87+
env: Env,
88+
policy: InsurancePolicy,
89+
) -> Result<(), Error> {
90+
policy.insurer.require_auth();
91+
92+
if policy.coverage_amount <= 0 || policy.deductible >= policy.coverage_amount {
93+
return Err(Error::InvalidPayment);
94+
}
95+
96+
let key = DataKey::Policy(policy.policy_id.clone());
97+
let store = env.storage().persistent();
98+
99+
if store.has(&key) {
100+
return Err(Error::AssetAlreadyExists);
101+
}
102+
103+
store.set(&key, &policy);
104+
105+
let mut list: Vec<BytesN<32>> = store
106+
.get(&DataKey::AssetPolicies(policy.asset_id.clone()))
107+
.unwrap_or_else(|| Vec::new(&env));
108+
109+
list.push_back(policy.policy_id.clone());
110+
store.set(&DataKey::AssetPolicies(policy.asset_id.clone()), &list);
111+
112+
log!(&env, "PolicyCreated: {:?}", policy.policy_id);
113+
Ok(())
114+
}
115+
116+
pub fn file_claim(
117+
env: Env,
118+
claim: InsuranceClaim,
119+
) -> Result<(), Error> {
120+
claim.claimant.require_auth();
121+
122+
let store = env.storage().persistent();
123+
let policy_key = DataKey::Policy(claim.policy_id.clone());
124+
125+
let policy: InsurancePolicy = store
126+
.get(&policy_key)
127+
.ok_or(Error::AssetNotFound)?;
128+
129+
if policy.status != PolicyStatus::Active {
130+
return Err(Error::Unauthorized);
131+
}
132+
133+
let key = DataKey::Claim(claim.claim_id.clone());
134+
if store.has(&key) {
135+
return Err(Error::AssetAlreadyExists);
136+
}
137+
138+
store.set(&key, &claim);
139+
140+
log!(&env, "ClaimFiled: {:?}", claim.claim_id);
141+
Ok(())
142+
}
143+
144+
pub fn approve_claim(
145+
env: Env,
146+
claim_id: BytesN<32>,
147+
approver: Address,
148+
) -> Result<(), Error> {
149+
approver.require_auth();
150+
151+
let store = env.storage().persistent();
152+
let key = DataKey::Claim(claim_id.clone());
153+
154+
let mut claim: InsuranceClaim = store.get(&key).ok_or(Error::AssetNotFound)?;
155+
156+
claim.status = ClaimStatus::Approved;
157+
claim.approved_amount = claim.amount;
158+
159+
store.set(&key, &claim);
160+
161+
log!(&env, "ClaimApproved: {:?}", claim_id);
162+
Ok(())
163+
}
164+
165+
pub fn pay_claim(
166+
env: Env,
167+
claim_id: BytesN<32>,
168+
) -> Result<(), Error> {
169+
let store = env.storage().persistent();
170+
let key = DataKey::Claim(claim_id.clone());
171+
172+
let mut claim: InsuranceClaim = store.get(&key).ok_or(Error::AssetNotFound)?;
173+
174+
if claim.status != ClaimStatus::Approved {
175+
return Err(Error::Unauthorized);
176+
}
177+
178+
claim.status = ClaimStatus::Paid;
179+
store.set(&key, &claim);
180+
181+
log!(&env, "ClaimPaid: {:?}", claim_id);
182+
Ok(())
183+
}
184+
185+
pub fn get_policy(env: Env, policy_id: BytesN<32>) -> Option<InsurancePolicy> {
186+
env.storage().persistent().get(&DataKey::Policy(policy_id))
187+
}
188+
189+
pub fn get_claim(env: Env, claim_id: BytesN<32>) -> Option<InsuranceClaim> {
190+
env.storage().persistent().get(&DataKey::Claim(claim_id))
191+
}

contracts/assetsup/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ pub(crate) mod audit;
88
pub(crate) mod branch;
99
pub(crate) mod error;
1010
pub(crate) mod types;
11+
pub(crate) mod insurance;
12+
1113

1214
pub use types::*;
1315

0 commit comments

Comments
 (0)