Skip to content

[MEDIUM] — recalculateCampaignStats never decrements raisedAmount after a refund, permanently inflating the campaign total #8

@Alqku

Description

@Alqku

Severity: Medium
Type: Bug
Scope: Campaigns, Donations
Labels: bug, help wanted, Official Campaign

Description

CampaignsService.recalculateCampaignStats (src/campaigns/campaigns.service.ts, lines ~270–286) sets raisedAmount = sum(donations where status = 'CONFIRMED'). It is invoked from createDonation after each successful confirmation.

The Donation.status enum supports REFUNDED (prisma/schema.prisma); when a refund flow lands, the underlying row flips from CONFIRMED to REFUNDED and is excluded from the aggregation. However, no caller ever re-runs recalculateCampaignStats on refund, so Campaign.raisedAmount continues to include the refunded value. Sequential refunds will monotonically grow the discrepancy between on-chain balance and recorded total.

Recommendation

  • After any state transition that flips a donation out of CONFIRMED (REFUNDED, FAILED), re-call recalculateCampaignStats from the same code path.
  • Add a Prisma $transaction that updates the status and the campaign aggregate atomically.
  • Add a regression test that issues a refund and asserts Campaign.raisedAmount decreases by exactly the refunded amount.

Metadata

Metadata

Labels

GrantFox OSSIssue tracked in GrantFox OSSMaybe RewardedIssue may be eligible for a GrantFox rewardOfficial CampaignAudit finding under the Official CampaignbugSomething isn't workinghelp wantedExtra attention is needed

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