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
2 changes: 2 additions & 0 deletions contracts/campaign-escrow/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,6 @@ pub enum Error {
ApplicationsExist = 22,
/// The metadata string must be non-empty.
InvalidMetadata = 23,
/// `max_creators` was set to zero when creating a campaign.
InvalidCreatorCount = 24,
}
7 changes: 5 additions & 2 deletions contracts/campaign-escrow/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ impl CampaignEscrowContract {
return Err(Error::AlreadyInitialized);
}
if !(0..=ads_bazaar_shared::BASIS_POINTS_DENOMINATOR).contains(&fee_bps) {
return Err(Error::InvalidAmount);
return Err(Error::FeeTooHigh);
}
admin.require_auth();

Expand Down Expand Up @@ -162,9 +162,12 @@ impl CampaignEscrowContract {
if !storage::is_initialized(&env) {
return Err(Error::NotInitialized);
}
if total_budget <= 0 || max_creators == 0 {
if total_budget <= 0 {
return Err(Error::InvalidAmount);
}
if max_creators == 0 {
return Err(Error::InvalidCreatorCount);
}
let now = env.ledger().timestamp();
if application_deadline <= now || completion_deadline <= now {
return Err(Error::DeadlineInPast);
Expand Down
159 changes: 158 additions & 1 deletion contracts/campaign-escrow/src/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ mod test_initialize {
&dispute,
&(ads_bazaar_shared::BASIS_POINTS_DENOMINATOR + 1),
);
assert_eq!(result, Err(Ok(Error::InvalidAmount)));
assert_eq!(result, Err(Ok(Error::FeeTooHigh)));
}

#[test]
Expand Down Expand Up @@ -706,6 +706,163 @@ mod test_deadline_enforcement {
}
}

mod test_error_variants {
use super::test_helpers::*;
use crate::{CampaignEscrowContractClient, Error};
use soroban_sdk::testutils::Address as _;
use soroban_sdk::{Address, Env, String};

#[test]
fn invalid_creator_count() {
let (env, _contract_id) = setup_env();
let (client, _admin, _dispute, _business, _token) = bootstrap(&env, &_contract_id, 50);

let business = Address::generate(&env);
let token = setup_token(&env, &business, 1_000_000);
let asset = usdc(&env, &token);

let now = env.ledger().timestamp();
let result = client.try_create_campaign(
&business,
&asset,
&1_000_000,
&0,
&(now + 86_400),
&(now + 604_800),
&String::from_str(&env, "ipfs://brief"),
);
assert_eq!(result, Err(Ok(Error::InvalidCreatorCount)));
}

#[test]
fn selection_limit_reached() {
let (env, contract_id) = setup_env();
let (client, _admin, _dispute, business, token) = bootstrap(&env, &contract_id, 0);
let id = create_funded_campaign(&env, &client, &business, &token, 2_000_000, 1);

let c1 = Address::generate(&env);
let c2 = Address::generate(&env);
client.apply_to_campaign(&c1, &id, &String::from_str(&env, "pitch1"));
client.approve_creator(&business, &id, &c1, &1_000_000);

client.apply_to_campaign(&c2, &id, &String::from_str(&env, "pitch2"));
let result = client.try_approve_creator(&business, &id, &c2, &1);
assert_eq!(result, Err(Ok(Error::MaxCreatorsReached)));
}

#[test]
fn budget_below_obligations() {
let (env, contract_id) = setup_env();
let (client, _admin, _dispute, business, token) = bootstrap(&env, &contract_id, 0);
let id = create_funded_campaign(&env, &client, &business, &token, 5_000_000, 5);

let c1 = Address::generate(&env);
client.apply_to_campaign(&c1, &id, &String::from_str(&env, "pitch1"));
client.approve_creator(&business, &id, &c1, &4_000_000);

let c2 = Address::generate(&env);
client.apply_to_campaign(&c2, &id, &String::from_str(&env, "pitch2"));
let result = client.try_approve_creator(&business, &id, &c2, &2_000_000);
assert_eq!(result, Err(Ok(Error::InsufficientEscrowBalance)));
}

#[test]
fn fee_too_high() {
let env = Env::default();
env.mock_all_auths();
let contract_id = env.register(crate::CampaignEscrowContract, ());
let client = CampaignEscrowContractClient::new(&env, &contract_id);
let admin = Address::generate(&env);
let dispute = Address::generate(&env);
let result = client.try_initialize(
&admin,
&dispute,
&(ads_bazaar_shared::BASIS_POINTS_DENOMINATOR + 1),
);
assert_eq!(result, Err(Ok(Error::FeeTooHigh)));
}

#[test]
fn invalid_deadline_order() {
let (env, contract_id) = setup_env();
let (client, _admin, _dispute, business, token) = bootstrap(&env, &contract_id, 50);

let now = env.ledger().timestamp();
let deadline = now + 300;
let asset = usdc(&env, &token);
let result = client.try_create_campaign(
&business,
&asset,
&10_000_000,
&5,
&deadline,
&deadline,
&String::from_str(&env, "ipfs://brief"),
);
assert_eq!(result, Err(Ok(Error::InvalidDeadlineOrder)));
}

#[test]
fn deadline_in_past() {
let (env, contract_id) = setup_env();
let (client, _admin, _dispute, business, token) = bootstrap(&env, &contract_id, 50);

let now = env.ledger().timestamp();
let asset = usdc(&env, &token);
let result = client.try_create_campaign(
&business,
&asset,
&10_000_000,
&5,
&(now - 100),
&(now + 604_800),
&String::from_str(&env, "ipfs://brief"),
);
assert_eq!(result, Err(Ok(Error::DeadlineInPast)));
}

#[test]
fn application_deadline_passed() {
let (env, contract_id) = setup_env();
let (client, _admin, _dispute, business, token) = bootstrap(&env, &contract_id, 50);

let now = env.ledger().timestamp();
let asset = usdc(&env, &token);
let id = client.create_campaign(
&business,
&asset,
&10_000_000,
&5,
&(now + 86_400),
&(now + 604_800),
&String::from_str(&env, "ipfs://brief"),
);
client.fund_campaign(&business, &id);

advance_time(&env, 86_400 + 10);

let creator = Address::generate(&env);
let result = client.try_apply_to_campaign(&creator, &id, &String::from_str(&env, "pitch"));
assert_eq!(result, Err(Ok(Error::ApplicationDeadlinePassed)));
}

#[test]
fn content_deadline_passed() {
let (env, contract_id) = setup_env();
let (client, _admin, _dispute, business, token) = bootstrap(&env, &contract_id, 50);
let id = create_funded_campaign(&env, &client, &business, &token, 10_000_000, 5);

let creator = Address::generate(&env);
client.apply_to_campaign(&creator, &id, &String::from_str(&env, "pitch"));
client.approve_creator(&business, &id, &creator, &1_000_000);

advance_time(&env, 604_800 + 10);

let result = client.try_submit_proof(&creator, &id, &String::from_str(&env, "proof"));
assert_eq!(result, Err(Ok(Error::ContentDeadlinePassed)));
}
}

mod test_version_upgrade {
use super::test_helpers::*;
use crate::Error;
Expand Down