Skip to content

[bug] campaign-lifecycle: TransitionCount grows without bound — unbounded on-chain transition history per campaign #642

@gboigwe

Description

@gboigwe

Summary

Every call to transition appends a StateTransition record under DataKey::Transition(campaign_id, count) and increments TransitionCount(campaign_id). There is no cap. A campaign that is repeatedly paused and resumed (e.g., by a fraud detection loop) accumulates unlimited transition records, each consuming persistent storage rent indefinitely. The pause_count field is also incremented without limit.

Location

contracts/campaign-lifecycle/src/lib.rs, transition

let count: u32 = env.storage().persistent().get(&DataKey::TransitionCount(campaign_id)).unwrap_or(0);
env.storage().persistent().set(&DataKey::Transition(campaign_id, count), &transition);
env.storage().persistent().set(&DataKey::TransitionCount(campaign_id), &(count + 1));
// ❌ No cap — count grows forever

Fix

Cap the ring-buffer approach (similar to campaign-analytics):

const MAX_TRANSITIONS: u32 = 100;
let index = count % MAX_TRANSITIONS;
env.storage().persistent().set(&DataKey::Transition(campaign_id, index), &transition);

Or only store the N most recent transitions.

Metadata

Metadata

Assignees

Labels

Stellar WaveIssues in the Stellar wave programbugSomething isn't working

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions