diff --git a/contracts/invoice-escrow/src/lib.rs b/contracts/invoice-escrow/src/lib.rs index 7262c4f..ce755c1 100644 --- a/contracts/invoice-escrow/src/lib.rs +++ b/contracts/invoice-escrow/src/lib.rs @@ -20,6 +20,8 @@ use types::{Config, EscrowData}; use errors::Error; const MAX_BPS: u32 = 10_000; +const MIN_ESCROW_DURATION: u64 = 86_400; // 1 day +const MAX_ESCROW_DURATION: u64 = 31_536_000; // 365 days const DISTRIBUTE_PAYMENT_FN: &str = "distribute_payment"; const DISTRIBUTE_REFUND_FN: &str = "distribute_refund"; @@ -116,6 +118,13 @@ impl InvoiceEscrow { if due_date <= current_timestamp { return Err(Error::InvalidDueDate); } + let duration = due_date.saturating_sub(current_timestamp); + if duration < MIN_ESCROW_DURATION { + return Err(Error::EscrowDurationTooShort); + } + if duration > MAX_ESCROW_DURATION { + return Err(Error::EscrowDurationTooLong); + } let config = storage::get_config(&env).ok_or(Error::NotInit)?; ensure_not_paused(&config)?; if storage::has_escrow(&env, invoice_id.clone()) { diff --git a/contracts/invoice-escrow/src/test.rs b/contracts/invoice-escrow/src/test.rs index bbbb882..db90e5e 100644 --- a/contracts/invoice-escrow/src/test.rs +++ b/contracts/invoice-escrow/src/test.rs @@ -2977,6 +2977,72 @@ fn test_create_escrow_due_date_zero_rejected() { assert_eq!(result, Err(Ok(Error::InvalidDueDate))); } +#[test] +fn test_create_escrow_due_date_too_short_rejected() { + let env = Env::default(); + env.mock_all_auths(); + + let escrow_id = env.register(InvoiceEscrow, ()); + let escrow_client = InvoiceEscrowClient::new(&env, &escrow_id); + + let admin = Address::generate(&env); + let seller = Address::generate(&env); + let payment_token = Address::generate(&env); + let inv_token = Address::generate(&env); + + escrow_client.initialize(&admin, &300); + + env.ledger().with_mut(|li| li.timestamp = 1_000_000); + let too_short_due_date = 1_000_000 + 86_399; + + let result = escrow_client.try_create_escrow( + &Symbol::new(&env, "INV_SHORT"), + &seller, + &seller, + &1000, + &950, + &too_short_due_date, + &payment_token, + &inv_token, + &test_commitment(&env, "short_due_date_test"), + &None, + ); + assert_eq!(result, Err(Ok(Error::EscrowDurationTooShort))); +} + +#[test] +fn test_create_escrow_due_date_too_long_rejected() { + let env = Env::default(); + env.mock_all_auths(); + + let escrow_id = env.register(InvoiceEscrow, ()); + let escrow_client = InvoiceEscrowClient::new(&env, &escrow_id); + + let admin = Address::generate(&env); + let seller = Address::generate(&env); + let payment_token = Address::generate(&env); + let inv_token = Address::generate(&env); + + escrow_client.initialize(&admin, &300); + + env.ledger().with_mut(|li| li.timestamp = 1_000_000); + let too_long_due_date = 1_000_000 + 31_536_001; + + let result = escrow_client.try_create_escrow( + &Symbol::new(&env, "INV_LONG"), + &seller, + &seller, + &1000, + &950, + &too_long_due_date, + &payment_token, + &inv_token, + &test_commitment(&env, "long_due_date_test"), + &None, + ); + assert_eq!(result, Err(Ok(Error::EscrowDurationTooLong))); +} + #[test] fn test_create_escrow_due_date_in_future_accepted() { let env = Env::default();