Summary
register_campaign stores end_ledger: u32 = 0 (and sets both original_end_ledger and current_end_ledger to 0) with no validation. A campaign registered with end_ledger = 0 is immediately past its deadline at any real ledger sequence. Any system component that checks env.ledger().sequence() > lifecycle.current_end_ledger would treat the campaign as expired from the first ledger it is active. Additionally, extend_campaign computes max_end = original_end_ledger.saturating_mul(3) = 0, so no extension is possible.
Location
contracts/campaign-lifecycle/src/lib.rs, register_campaign
pub fn register_campaign(env: Env, advertiser: Address, campaign_id: u64, end_ledger: u32) {
// ❌ No: if end_ledger <= env.ledger().sequence() { panic!(...) }
Fix
if end_ledger <= env.ledger().sequence() {
panic!("end_ledger must be in the future");
}
Summary
register_campaignstoresend_ledger: u32 = 0(and sets bothoriginal_end_ledgerandcurrent_end_ledgerto 0) with no validation. A campaign registered withend_ledger = 0is immediately past its deadline at any real ledger sequence. Any system component that checksenv.ledger().sequence() > lifecycle.current_end_ledgerwould treat the campaign as expired from the first ledger it is active. Additionally,extend_campaigncomputesmax_end = original_end_ledger.saturating_mul(3) = 0, so no extension is possible.Location
contracts/campaign-lifecycle/src/lib.rs,register_campaignFix