Skip to content
Merged
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
44 changes: 44 additions & 0 deletions quicklendx-contracts/src/test_insurance_claim_payout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -542,3 +542,47 @@ fn test_add_insurance_rejected_after_due_date() {
"the rejected opt-in must not create an extra coverage record"
);
}

#[test]
fn test_add_insurance_rejected_when_timestamp_past_due_date() {
let env = Env::default();
let (client, admin, _) = setup(&env);

let business = create_verified_business(&env, &client, &admin);
let investor = create_verified_investor(&env, &client, &admin, 10_000);

let amount = 1_000i128;
// Set a due date that is 2 days in the future from the initial ledger time.
let due_date = env.ledger().timestamp() + 2 * 86_400;
let invoice_id = create_and_fund_invoice(
&env, &client, &admin, &business, &investor, amount, due_date,
);

let investment = client.get_invoice_investment(&invoice_id);
let investment_id = investment.investment_id;

// --- Advance time past the due date (timestamp > due_date) ---
let past_due_time = due_date + 1; // 1 second after due date
env.ledger().set_timestamp(past_due_time);

// --- Opt-in attempt when timestamp > due_date must be rejected ---
let provider = Address::generate(&env);
let result = client.try_add_investment_insurance(&investment_id, &provider, &50u32);
assert!(
result.is_err(),
"insurance opt-in must be rejected when timestamp > due_date"
);
assert_eq!(
result.unwrap_err().unwrap(),
crate::errors::QuickLendXError::InsuranceClaimWindowClosed,
"error must be InsuranceClaimWindowClosed (1410), not a generic error"
);

// Confirm no policy was recorded.
let records = client.query_investment_insurance(&investment_id);
assert_eq!(
records.len(),
0,
"the rejected opt-in must not create a coverage record"
);
}
50 changes: 50 additions & 0 deletions quicklendx-contracts/src/test_multisig.rs
Original file line number Diff line number Diff line change
Expand Up @@ -231,3 +231,53 @@ fn test_verify_op_invalid_signature() {
// Verification must fail cryptographically (panics with HostError)
client.verify_op(&message_hash, &signatures);
}

#[test]
fn test_verify_op_over_quorum() {
let env = Env::default();
let contract_id = env.register(MultisigContract, ());
let client = MultisigContractClient::new(&env, &contract_id);

// Generate keys for N = 3 owners
let (pub0, priv0) = generate_keypair(&env, 1);
let (pub1, priv1) = generate_keypair(&env, 2);
let (pub2, priv2) = generate_keypair(&env, 3);

let mut owners = Vec::new(&env);
owners.push_back(pub0);
owners.push_back(pub1);
owners.push_back(pub2);

// Initialize with threshold = 2
client.initialize(&owners, &2);

let message_hash = BytesN::from_array(&env, &[9u8; 32]);
let message_bytes: [u8; 32] = [9u8; 32];

// All 3 owners sign the message (over quorum: 3 > threshold 2)
let sig0_bytes = priv0.sign(&message_bytes).to_bytes();
let sig1_bytes = priv1.sign(&message_bytes).to_bytes();
let sig2_bytes = priv2.sign(&message_bytes).to_bytes();

let sig0 = BytesN::from_array(&env, &sig0_bytes);
let sig1 = BytesN::from_array(&env, &sig1_bytes);
let sig2 = BytesN::from_array(&env, &sig2_bytes);

let mut signatures = Vec::new(&env);
signatures.push_back(OwnerSignature {
owner_index: 0,
signature: sig0,
});
signatures.push_back(OwnerSignature {
owner_index: 1,
signature: sig1,
});
signatures.push_back(OwnerSignature {
owner_index: 2,
signature: sig2,
});

// Verification should succeed even with more signatures than threshold
let res = client.try_verify_op(&message_hash, &signatures);
assert!(res.is_ok());
}
Loading